通过Interface扫描获取所有其实现类
当我们在代码中定义了一个接口,很多功能累实现了这个接口。所以我们可以统一管理这个接口,避免自己手动创建对象。避免在后续的新功能假如是实现时修改过多的代码,而导致意外出现。
ClassPathScanningCandidateComponentProvider提供了一个从指定包中扫面接口实现类的功能。
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AssignableTypeFilter(BaseHandler.class));
Set<BeanDefinition> definitionSet = provider.findCandidateComponents("com.test.xxxx.handler");
for (BeanDefinition beanDefinition : definitionSet) {Class<?> clazz = Class.forName(beanDefinition.getBeanClassName());LOGGER.info("初始化数据同步处理service:{}", beanDefinition.getBeanClassName());BaseHandler handler= (BaseHandler) clazz.newInstance();//其他的业务逻辑,可以用map统一管理//例如接口中加如一个方法,强制实现类实现,并给出自己的唯一IdHandlerDto handlerDto = service.getUnique();}
这样我们就可以获取到所有的实现类并在需要的时候,传入参数获取其对象。
完整实现测试如下:
接口:
public interface BaseHandler {/*** 获取处理器的唯一编码 */DataHandlerDto getUnique();/*** 业务实现逻辑*/void dealData(Object obj);
}
统一管理和获取实现对象
@Component
public class HnadlerManager {public static final Map<HandlerDto, Class< ? extends BaseHandler>> HANDLER_SERVICE_MAP = new HashMap<>();@PostConstructprivate static void initOperateService(){LOGGER.info("初始化数据同步处理handler");registerCollect();}private static void registerCollect(){ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);provider.addIncludeFilter(new AssignableTypeFilter(BaseHandler.class));Set<BeanDefinition> definitionSet = provider.findCandidateComponents("com.eshore.cnomp.handler");try {for (BeanDefinition beanDefinition : definitionSet) {Class<?> clazz = Class.forName(beanDefinition.getBeanClassName());LOGGER.info("初始化数据同步处理service:{}", beanDefinition.getBeanClassName());BaseHandler service = (BaseHandler) clazz.newInstance();HandlerDto handlerDto = service.getUnique();boolean iscontain = false;for(Map.Entry<HandlerDto,Class< ? extends BaseHandler>> entry: HANDLER_SERVICE_MAP.entrySet()){HandlerDto dto = entry.getKey();if(dto.getId.equals(handlerDto.getId())){iscontain = true;LOGGER.info("已存在相同数据同步处理类:{}, {}",entry.getValue().getName(), JSON.toJSONString(dto));}}if(!iscontain){HANDLER_SERVICE_MAP.put(HandlerDto, service.getClass());}}}catch (Exception e){LOGGER.error("初始化数据同步处理service失败", e);throw new RuntimeException("初始化数据同步处理service失败");}}public static BaseHandler getHandler(String id){for(Map.Entry<HandlerDto,Class< ? extends BaseHandler>> entry: HANDLER_SERVICE_MAP.entrySet()){HandlerDto dto = entry.getKey();if(dto.getId.equals(id)){Class<? extends BaseHandler> clazz = entry.getValue();try {return clazz.newInstance();} catch (Exception e) {LOGGER.error("构建采集兑现失败", e);return null;}}}return null;}}
以上实现是单个兑现的实现。如果需要以链路的方式,即同一个对象可以被多个处理器顺序处理,则需要调整其存储的方式为list并加入排序。