当前位置: 代码网 > it编程>编程语言>Java > 通过Interface扫描获取所有实现类方式

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

2025年11月19日 Java 我要评论
通过interface扫描获取所有实现类当我们在代码中定义了一个接口,很多功能累实现了这个接口。所以我们可以统一管理这个接口,避免自己手动创建对象。避免在后续的新功能假如是实现时修改过多的代码,而导致

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

总结

这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com