通过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并加入排序。
总结
这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论