通过Interface扫描获取所有实现类方式

 更新时间:2025年11月19日 10:06:32   作者:码上走人  
文章介绍了如何使用ClassPathScanningCandidateComponentProvider从指定包中扫描接口实现类,并通过接口统一管理和获取实现对象,这种方法避免了手动创建对象和修改代码的问题,并且可以处理链路方式下的多处理器顺序处理

通过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统一管理
       //例如接口中加如一个方法,强制实现类实现,并给出自己的唯一Id
       HandlerDto 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<>();


    @PostConstruct
    private 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并加入排序。

总结

这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java防止频繁请求、重复提交的操作代码(后端防抖操作)

    Java防止频繁请求、重复提交的操作代码(后端防抖操作)

    在客户端网络慢或者服务器响应慢时,用户有时是会频繁刷新页面或重复提交表单的,这样是会给服务器造成不小的负担的,同时在添加数据时有可能造成不必要的麻烦,今天通过本文给大家介绍下Java防止频繁请求、重复提交的操作代码,一起看看吧
    2022-04-04
  • 学习java一定要知道的垃圾收集器

    学习java一定要知道的垃圾收集器

    这篇文章主要介绍了学习java一定要知道的垃圾收集器,垃圾收集器的发展路线,简单来说是随着内存越来越大而发生变化,更多相关介绍需要的朋友可以参考一下
    2022-07-07
  • Java常见面试题之final在java中的作用是什么

    Java常见面试题之final在java中的作用是什么

    这篇文章主要介绍了Java常见面试题之final在java中的作用是什么,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • 详解Java线程中断知识点

    详解Java线程中断知识点

    在本篇文章中我们给大家分享了关于Java线程中断的相关知识点内容以及相关代码实例,有兴趣的朋友们可以学习下。
    2018-09-09
  • AQS同步组件Semaphore信号量案例剖析

    AQS同步组件Semaphore信号量案例剖析

    这篇文章主要为大家介绍了AQS同步组件Semaphore信号量案例剖析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • SpringCloud大文件分片断点上传实现原理

    SpringCloud大文件分片断点上传实现原理

    这篇文章主要介绍了SpringCloud大文件分片断点上传实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • Java String类用法详解

    Java String类用法详解

    今天给大家带来的是关于Java的相关知识,文章围绕着Java String类用法展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • java.io.IOException: UT010029: Stream is closed异常分析及解决

    java.io.IOException: UT010029: Stream is closed异常分析及解决

    这篇文章主要给大家介绍了关于java.io.IOException: UT010029: Stream is closed异常分析及解决办法,文中通过代码介绍的非常详细,对大家的学习或者工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-02-02
  • Java中将String转换为int的多种方法

    Java中将String转换为int的多种方法

    字符串转换为整数是一个常见需求,本文主要介绍了Java中将String转换为int的多种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-07-07
  • 使用idea自动生成序列化ID全过程

    使用idea自动生成序列化ID全过程

    这篇文章主要介绍了使用idea自动生成序列化ID全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09

最新评论