赞
踩
开发中需要一个与其他系统对接数据的公共接口,然后通过TYPE字段来区分不同的接口。如果用if else或者switch case来写则会很长维护不是很方便,想法是让所有的数据接口类实现同一个接口,然后定义一个工具类将接口类型与对应的实体类放在map中,key为类型,相当于以多态的方式实现。
主要代码:
Controller
@Autowired
private DataInterfaceUtil dataInterfaceUtil;//注入工具类
@GetMapping("/getData")
public void getData(){
try{
String type="TEST1";
String jsonParam="......";
DataInterface dataInterface = dataInterfaceUtil.getDataInterfaceByType(type);
dataInterface.execute(jsonParam);
}catch (Exception e){
}
}
工具类,在工具类中使用@PostConstruct,使用@autowired进行注入实际上调用的就是默认无参构造,如果将interfaceMap的初始化放在构造函数中则会出现接口中的Mapper为null的现象。
原因是在Controller中注入工具类时首先会调用工具类的构造方法,而此时testDataInterface还没有完成注入,所以map中数据全部为空,如果传入的是 new TestDataInterface那么里面的Mapper必然是无法注入的,这个就是废话了,而解决的办法就是首先让工具类中的属性先完成注入,然后再初始化map,而使用@PostConstruct注解就是将方法作为该bean的初始化方法,该方法在构造函数后执行,也就是将该bean中所有的属性注入完成后才会执行,所以此时的map中的数据不为空了,mapper也可以完成注入。
/** * @author lijianan * @date 2020-11-05 20:47 * @description 接口工具类 */ @Component public class DataInterfaceUtil { @Autowired private TestDataInterface testDataInterface; //接口map private Map<String, DataInterface> interfaceMap; DataInterfaceUtil(){ interfaceMap=new HashMap<>(); /** 在此处初始化时会导致Mapper注入为null interfaceMap.put("TEST1",testDataInterface); interfaceMap.put("TEST2",testDataInterface); interfaceMap.put("TEST3",testDataInterface); interfaceMap.put("TEST4",testDataInterface); **/ } @PostConstruct void init(){ interfaceMap.put("TEST1",testDataInterface); interfaceMap.put("TEST2",testDataInterface); interfaceMap.put("TEST3",testDataInterface); interfaceMap.put("TEST4",testDataInterface); } //根据类型获取对应接口实例 public DataInterface getDataInterfaceByType(String type) throws Exception { DataInterface dataInterface = interfaceMap.get(type); if(null==dataInterface){ throw new Exception("未找到对应接口"); } return dataInterface; } }
接口实现类:接口实现类中将mapper打印出来,观察是否成功注入
/** * @author lijianan * @date 2020-11-05 20:53 * @description TestDataInterface Class */ @Component public class TestDataInterface implements DataInterface{ @Autowired private CodeMapperExt codeMapperExt;//注入mapper @Override public Result execute(String jsonParam) throws Exception { System.out.println(codeMapperExt);//查看是否成功注入 return null; } }
执行的结果为 org.apache.ibatis.binding.MapperProxy@63bafd20,说明已经注入成功了。其实在上面在工具类中注入接口实现类还是有写硬编码,既然用Spring完全可以使用自定义注解,比如@DataInterfaceInfo(type=“TEST1”,name=“测试接口”),在调用init()方法时获取所有使用该注解的bean,并将他们放到map中,这样就更方便一些,或者实现BeanPostProcessor接口对所有的bean初始化做特殊操作,这个有时间再搞一下。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。