1.重构的时候遇到Spring按Type装载匹配的Bean的异常,当有两个具象类且是父子关系时(如下图, 父类SPParser4ItemAOImpl和子类SPParser4BrandAOImpl), 通过Spring容器ApplicationContext.getBean按type装载匹配父类时,会匹配到两个实例(自己SPParser4ItemAOImpl和子类SPParser4BrandAOImpl), 装载子类时,只会找到子类实例本身(SPParser4BrandAOImpl). 有兴趣可看下DefaultListableBeanFactory.doGetBeanNamesForType方法, 用了xxx.class.isInstance(beanInstance)去判断.
@Component
public class SPParser4BrandAOImpl extends SPParser4ItemAOImpl {
@Override
public void parseDataList() {
System.out.println("This is in SPParser4BrandAOImpl");
}
}
@Component
public class SPParser4ItemAOImpl extends SuperSPPageFloorParseAO {
@Override
public void parseDataList() {
System.out.println("This is in SPParser4ItemAOImpl");
}
}
public abstract class SuperSPPageFloorParseAO implements SPPageFloorParserAO {
@Override
public Map<String, String> parseAttrMap() {
return new HashMap<>();
}
}
public interface SPPageFloorParserAO {
void parseDataList();
/**
* 获取 SPPageFloorVO attrMap数据
* @return
*/
Map<String, String> parseAttrMap();
}
@Component
public class SPParser4BannerAOImpl extends SuperSPPageFloorParseAO {
public void parseDataList() {
//是banner的话就进行url组装
System.out.println("This is in SPParser4BannerAOImpl");
}
}
注意,调用的地方是找各自具象类
SPParser4ItemAOImpl sPParser4ItemAOImpl = (SPParser4ItemAOImpl) context.getBean(SPParser4ItemAOImpl.class);
SPParser4BrandAOImpl sPParser4BrandAOImpl = (SPParser4BrandAOImpl) context.getBean(SPParser4BrandAOImpl.class);
2.Spring自动装配匹配类跟使用的地方是有关联的,如果使用的地方按接口类型或父类去查找, 会匹配到所有实现了接口类型和父类的具象类(SPParser4BannerAOImpl,SPParser4BrandAOImpl,SPParser4ItemAOImpl),程序会报错.
@Component
public class TestApp {
@Autowired
private SPPageFloorParserAO sPPageFloorParserAO;
public void test(){
sPPageFloorParserAO.parseDataList();
}
}
@Autowired
private SuperSPPageFloorParseAO superSPPageFloorParseAO;
public void testSuperClass(){
superSPPageFloorParseAO.parseDataList();
}
解决TestApp的依赖注入时,还是用xxx.class.isInstance(beanInstance)去判断.
3. 在使用Spring注解如 @Component 注册为组件时,如果没有指定名字 @Component("指定的名字"), 而是默认的话,如果class名称为 ABxxx 时会直接返回,而不会将 A 转为小写,因为Spring的判断是:如果第二位是大写,则直接返回.有兴趣可看类AnnotationBeanNameGenerator的generateBeanName和buildDefaultBeanName方法.
4. Qualifier如果在父子具象类中使用,如果Qualifier仅标在父具象类中,通过@Autowired和@Qualifier找父类也会找到两个,还需要把@Qualifier标注在子类上,这样Autowired父类只会找到一个.
@Component
//@Primary
@Qualifier("cold")
public class SPParser4ItemAOImpl extends SuperSPPageFloorParseAO {
@Override
public void parseDataList() {
System.out.println("This is in SPParser4ItemAOImpl");
}
}
@Component
//@Qualifier("需要增加一个新标识跟父类标识区分")
public class SPParser4BrandAOImpl extends SPParser4ItemAOImpl {
@Override
public void parseDataList() {
System.out.println("This is in SPParser4BrandAOImpl");
}
}
@Component
public class TestApp {
@Autowired
//@Qualifier("SPParser4ItemAOImpl")
@Qualifier("cold")
private SPPageFloorParserAO sPPageFloorParserAO;
public void test(){
sPPageFloorParserAO.parseDataList();
}
}
@Test
public void testGetBeanByClazz() {
TestApp testApp = context.getBean(TestApp.class);
testApp.test();
}
- 大小: 13.8 KB
- 大小: 68 KB
分享到:
相关推荐
elicpse配置spring文件自动提示截图,通过快捷键Ctrl+/ 可以自动不全
类名查看器类名查看器类名查看器类名查看器类名查看器类名查看器
Ubuntu下的自动获取android包名类名,操作简单。
VC修改窗口类名
解决jar包类名冲突问题
springBean加载过程源码解析文档,附有代码类名和行数
易语言控件随机类名源码,更改易语言窗口及窗口内所有控件的类名
易语言修改窗口类名易语言源码,能用,易语言修改窗口类名.e
易语言模块动态类名.rar 易语言模块动态类名.rar 易语言模块动态类名.rar 易语言模块动态类名.rar 易语言模块动态类名.rar 易语言模块动态类名.rar
通过逆向的smali文件中因为proguard混淆后会形成包名类名相同的问题,这样逆向的代码不能用,此工具通过修改smali文件中的类名,可以帮你讲重名的换成其他,
java的主题类名
获取apk包名类名,将apk安装到手机或者模拟器可以获取当前app的包名类名
控件类名查看器 可以查看软件中控件的类名
当我们要编写对外部程序进行控制,实现操作自动化的软件时,就需要获得外部程序窗口与窗口中指定控件的各层级类名属性,本软件可以实现此目的。将鼠标放置在外部程序窗口中指定控件上,时间超过3秒钟,本软件就会...
qt通过类名动态创建对象
该工具,可以获取apk的包名和类名,是一个很实用的小工具.
用APIHOOKAPIHOOK实现易语言动态类名,属于易语言中级教程源码
易语言做外挂 修改类名 防止游戏检测外挂非法
易语言拦截消息修改窗口类名源码,拦截消息修改窗口类名,MyCreateWindowEx,InstallApiHook,BeginHook,StopHook,UninstallApiHook,GetApiHookInfo,CreateWindowExA,RegisterClassExA,GetClassInfoExA,UnregisterClassA...
获取窗体的句柄,类名,标题,进程名称,进程路径,进程ID,线程ID