通过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并加入排序。

总结

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

相关文章

  • Spring Boot中@Import三种使用方式实例详解

    Spring Boot中@Import三种使用方式实例详解

    这篇文章主要介绍了Spring Boot中@Import三种使用方式,主要有引入普通类,引入importSelector的实现类及引入importBeanDefinitionRegister的实现类,结合实例代码给大家讲解的非常详细,需要的朋友可以参考下
    2022-11-11
  • Java判断范围型的数据是否存在重叠的方法

    Java判断范围型的数据是否存在重叠的方法

    遇到了个问题,同一天可以输入多个时间段,但是每个时间段的时间不能出现重叠,这不就是判断数据返回是否有重叠的变种吗,所以本文给大家介绍了Java判断范围型的数据是否存在重叠的方法,需要的朋友可以参考下
    2024-07-07
  • 对Java中传值调用的理解分析

    对Java中传值调用的理解分析

    这篇文章主要介绍了对Java中传值调用的理解分析,通过分析对比,较为深入的分析了Java中传值调用的原理与用法,需要的朋友可以参考下
    2015-01-01
  • SpringBoot整合Jackson超详细用法(附Jackson工具类)

    SpringBoot整合Jackson超详细用法(附Jackson工具类)

    这篇文章主要介绍了SpringBoot整合Jackson超详细教程,本篇讲的是Jackson的详细用法,Jackson工具类在文章最后,直接复制粘贴即可使用,需要的朋友可以参考下
    2023-03-03
  • java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

    java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

    这篇文章主要介绍了java.sql.SQLTransientConnectionException连接超时异常原因及解决方案,通过文中介绍的方法可以帮助开发者快速定位并解决连接超时问题,需要的朋友可以参考下
    2025-09-09
  • IDEA如何实现查看UML类图

    IDEA如何实现查看UML类图

    这篇文章主要介绍了IDEA如何实现查看UML类图问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • Spring的事务管理你了解吗

    Spring的事务管理你了解吗

    这篇文章主要为大家介绍了Spring的事务管理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • mybatis-plus多表分页查询最佳实现方法(非常简单)

    mybatis-plus多表分页查询最佳实现方法(非常简单)

    这篇文章主要给大家介绍了关于mybatis-plus多表分页查询最佳实现方法,文中介绍的方法非常简单,MyBatis-Plus中分页查询是比较方便的,这个功能在网站中也是非常常用的,这方面的知识点是必备的知识点,需要的朋友可以参考下
    2023-08-08
  • Java实现生产者消费者问题与读者写者问题详解

    Java实现生产者消费者问题与读者写者问题详解

    这篇文章主要介绍了Java实现生产者消费者问题与读者写者问题详解,小编觉得挺不错的,这里分享给大家,供需要的亲朋好友参考。
    2017-11-11
  • Mybatis Plugin拦截器开发过程详解

    Mybatis Plugin拦截器开发过程详解

    这篇文章主要介绍了Mybatis Plugin拦截器开发过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02

最新评论