spring 之 注入之 by name or by type, or both ?
@Autowired 和 @Qualifier
使用xml 注入的时候, 我们可以指定 autowire=“byType” 或“byName” 。
但是使用 注解的时候, @Autowired 只有一个 required 属性, 无法设置 by name或者 by type。 那么 这个时候, 我们可以使用 @Qualifier
@Autowired @Qualifier 需要一起使用,他们是一个奇怪的组合, 组合到一起的时候, 表示,先尝试 by type, 出现冲突了,那么by name。 换句话说, 如果需要注入的某个类型的bean ,只有一个实例, 对应 @Autowired @Qualifier 组合, 其中@Qualifier 可有可无, 有的话, 其 value 可以随便写。但是 如果有多个, 那就不一样的: 此时,@Qualifier也必须正确。
关于 @Bean
spring 在解析到 @Bean 的时候, 会自动给 参数中的 对象类型 注入 一个实例, 默认byType , 不需要 @Autowired 或者 @Qualifier
@Bean
public LkCar datasource(LkBean lkBean) {
System.out.println("config datasrouce.");
return new LkCar(lkBean);
} @Bean
public LkBean aa() {
System.out.println("config bean aa");
LkBean bean = new LkBean();
bean.setStr("aa");
return bean;
} @Bean("bb")
// @Primary
public LkBean aabb() {
System.out.println("config bean bb");
LkBean bean = new LkBean();
bean.setStr("bb");
return bean;
}
java config 默认是使用 byType注册。 上面的代码中, 有两个类型为 LkBean的实例, 故实例化 LkCar的时候出错:
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'datasource' defined in com.anno.LkAnno: Unsatisfied dependency expressed through method 'datasource' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.anno.LkBean' available: expected single matching bean but found 2: aa,bb
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:467)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1134)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1028)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:759)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
at AnnoIo22CTest.main(AnnoIo22CTest.java:10)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.anno.LkBean' available: expected single matching bean but found 2: aa,bb
at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:172)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1114)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
... 19 more
解决方法有两个,
1 在其中一个参数bean 的方法上面添加 @Primary , 表明它是首选
2 把 datasource 签名改为:
public LkCar datasource(@Qualifier("bb")LkBean lkBean) {
...
这里的 @Autowired 是不需要的。 @Qualifier 必须放到 方法的参数中去, 而不是在 方法之上。
另外, 当一个类中有两个@Bean , 比如一个 为方法aa, 另一个返回值相同,但是@Bean("aa"), 那么, 前面的生效, 后面的无法注册为 spring 的bean, 因为已经注册过了一次了!
另外, 当我们有多个配置类的时候, 它们是会合并的,合并的规则是:
如果没有同名bean ,当然就简单的组合到一起就行了。
如果有冲突呢? 后面出现的覆盖前面的!! 这和 在一个 java config 中出现冲突的处理 顺序是相反的!!
另外, 我发现, 当我 @Autowire 一个 方法的时候, 如果在当前类有多个可选同类型 bean 实例,那么 会出错, 但是如果其他的 java config 配置类 还有一个 可选的同类型bean 实例, 那么就不会出错。
真是奇了怪了。 究其原因, 应该是 跟 bean 实例化的顺序有关, 如果 在Autowire 一个 方法的时候, 能够找到一个实例, 而不是多个, 那么久使用它。 否则如果发现多个, 那么久不行。!!
注意: @Bean 或者 java config 仅仅是定义及 注册了 bean 的定义, 真正的实例化是 在第一次使用它的时候(如果有冲突, 是这个时候才会发现)。
spring 之 注入之 by name or by type, or both ?的更多相关文章
- Spring自动注入properties文件
实现spring 自动注入属性文件中的key-value. 1.在applicationContext.xml配置文件中,引入<util />命名空间. xmlns:util=" ...
- spring 属性注入
Spring的核心技术室依赖注入,下面是依赖注入之属性注入的实现过程,牛刀小试,请看效果. 1.首先添加Spring.Web引用.本例中是使用分层思想来演示的,下面是项目的结构和UserModel类的 ...
- spring 多线程 注入 服务层 问题
在用多线程的时候,里面要用到Spring注入服务层,或者是逻辑层的时候,一般是注入不进去的.具体原因应该是线程启动时没有用到Spring实例不池.所以注入的变量值都为null. 详细:http://h ...
- Spring 依赖注入方式详解
平常的Java开发中,程序员在某个类中需要依赖其它类的方法. 通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理. Spring提出了依赖注入的思想,即依赖类不由 ...
- Spring的注入问题
作下笔记,Spring的注入问题[多个实例问题] 解决方案如下: package student.life.support.platform.service.impl; import javax.an ...
- Spring依赖注入(IOC)那些事
小菜使用Spring有几个月了,但是对于它的内部原理,却是一头雾水,这次借着工作中遇到的一个小问题,来总结一下Spring. Spring依赖注入的思想,就是把对象交由Spring容器管理,使用者只需 ...
- Spring依赖注入三种方式详解
在讲解Spring依赖注入之前的准备工作: 下载包含Spring的工具jar包的压缩包 解压缩下载下来的Spring压缩包文件 解压缩之后我们会看到libs文件夹下有许多jar包,而我们只需要其中的c ...
- Spring依赖注入:注解注入总结
更多11 spring 依赖注入 注解 java 注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired.Resource.Qualifier.S ...
- Spring 依赖注入,在Main方法中取得Spring控制的实例
Spring依赖注入机制,在Main方法中通过读取配置文件,获取Spring注入的bean实例.这种应用在实训的时候,老师曾经说过这种方法,而且学Spring入门的时候都会先学会使用如何在普通的jav ...
随机推荐
- mysql 在 win 安装 最全攻略(附转载的乱码终极解决方案)以及解决data too long for column 'name' at row 1, 一种可能就是因为编码一致性问题.
[博客园cnblogs笔者m-yb原创,转载请加链接,公众号aandb7, github.com/mayangbo666,QQ群927113708] https://www.cnblogs.com/m ...
- raid的一些简单知识
日一.RAID定义RAID(Redundant Array of Independent Disk 独立冗余磁盘阵列)技术是加州大学伯克利分校1987年提出,最初是为了组合小的廉价磁盘来代替大的昂贵磁 ...
- wed
先有一个无后缀的flag 文件 第一次改成 TXT 收索FLAG 得到了一段 flag.txt f返回到第一次修改后缀 改成RAR 打开RAR 发现一个 flag.txt 的文件 打开,即得到 fla ...
- guava-retrying 源码解析(导入项目)
1.从github上下载guava-retry源码 git clone git://github.com/rholder/guava-retrying.git 2.导入idea,使用gradle记得勾 ...
- [转]Spark学习之路 (三)Spark之RDD
Spark学习之路 (三)Spark之RDD https://www.cnblogs.com/qingyunzong/p/8899715.html 目录 一.RDD的概述 1.1 什么是RDD? ...
- 【转】20-TCP 协议(滑动窗口——基础)
https://blog.csdn.net/q1007729991/article/details/70142341 相信大家都遇到过这样的场景: 同学 Luffy 给你打电话,让你记下一串手机号码, ...
- java基础(4)继承和多态
1 继承 1.1 继承概述 继承要解决的问题:共性抽取 1.2 继承的格式 class 父类 { ... } class 子类 extends 父类 { ... } 1.3 继承中成员变量的特点(变 ...
- CORS(跨域资源共享)的防御机制
一.为什么会出现CORS: 浏览器的同源策略给WEB开发人员带来了巨大的痛苦,信息的交互共享本来就是网络的意义.所以妥协之后出现了CORS. 二.技术原理: 1.简单跨域: (1)方法要求:只能是GE ...
- 解决eclipse高版本JDK编译的项目到低版本JDK服务器上不能运行的问题
错误提示信息:Unsupported major.minor version 52.0,意思是说,当前jdk的版本不支持更高版本jdk编译出来的class文件. 我的编译环境,eclipse使用的是j ...
- robot framework下载文件操作
不同的浏览器点击[下载]按钮之后,需要点击保存,还是确定,或者直接默认直接下载都是不一样的 1.chrome:点击[下载]之后,会自动执行下载操作,直到下载结束 A)点击下载,等待下载结束(sleep ...