@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 ?的更多相关文章

  1. Spring自动注入properties文件

    实现spring 自动注入属性文件中的key-value. 1.在applicationContext.xml配置文件中,引入<util />命名空间. xmlns:util=" ...

  2. spring 属性注入

    Spring的核心技术室依赖注入,下面是依赖注入之属性注入的实现过程,牛刀小试,请看效果. 1.首先添加Spring.Web引用.本例中是使用分层思想来演示的,下面是项目的结构和UserModel类的 ...

  3. spring 多线程 注入 服务层 问题

    在用多线程的时候,里面要用到Spring注入服务层,或者是逻辑层的时候,一般是注入不进去的.具体原因应该是线程启动时没有用到Spring实例不池.所以注入的变量值都为null. 详细:http://h ...

  4. Spring 依赖注入方式详解

    平常的Java开发中,程序员在某个类中需要依赖其它类的方法. 通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理. Spring提出了依赖注入的思想,即依赖类不由 ...

  5. Spring的注入问题

    作下笔记,Spring的注入问题[多个实例问题] 解决方案如下: package student.life.support.platform.service.impl; import javax.an ...

  6. Spring依赖注入(IOC)那些事

    小菜使用Spring有几个月了,但是对于它的内部原理,却是一头雾水,这次借着工作中遇到的一个小问题,来总结一下Spring. Spring依赖注入的思想,就是把对象交由Spring容器管理,使用者只需 ...

  7. Spring依赖注入三种方式详解

    在讲解Spring依赖注入之前的准备工作: 下载包含Spring的工具jar包的压缩包 解压缩下载下来的Spring压缩包文件 解压缩之后我们会看到libs文件夹下有许多jar包,而我们只需要其中的c ...

  8. Spring依赖注入:注解注入总结

    更多11   spring   依赖注入   注解   java 注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired.Resource.Qualifier.S ...

  9. Spring 依赖注入,在Main方法中取得Spring控制的实例

    Spring依赖注入机制,在Main方法中通过读取配置文件,获取Spring注入的bean实例.这种应用在实训的时候,老师曾经说过这种方法,而且学Spring入门的时候都会先学会使用如何在普通的jav ...

随机推荐

  1. dom4j操作xml的demo

    package com.cn.shop.util; import java.io.File;import java.io.FileOutputStream;import java.io.OutputS ...

  2. 面向对象 反射 和item系列和内置函数和__getattr__和__setattr__

    反射 反射主要用在网络编程中, python面向对象的反射:通过字符串的形式操作对象相关的属性.python的一切事物都是对象. 反射就是通过字符串的形式,导入模块:通过字符串的形式,去模块寻找指定函 ...

  3. java基础(7)集合与泛型

    第一部分:Collection集合 1 collection集合概述 集合按照其存储结构可以分为两大类,分别是单列集合java.util.Collection和双列集合java.util.Map. C ...

  4. java基础(4)继承和多态

    1 继承 1.1  继承概述 继承要解决的问题:共性抽取 1.2 继承的格式 class 父类 { ... } class 子类 extends 父类 { ... } 1.3 继承中成员变量的特点(变 ...

  5. Dubbo的全局Filter配置

    前言: 之前也写过dubbo的filter的文章, 后来和同事也有过交流, 才发生自己对dubbo的filter的机制, 还是存在一些误解, 尤其是自定义filter的定位, 不是那么清晰. 本文主要 ...

  6. freeswitch黑名单mod_blacklist使用

    freeswitch自带黑名单模块"mod_blacklist",此文只是对该模块简单使用的实例. 最近接到客户投诉有大量骚扰电话,而从源头查不太容易,因此想到的笨方法是将投诉人加 ...

  7. Restful架构学习

    Restful规范的架构是一种简洁并且面向资源的规范方式,其概念和起源大家google一下就好. 以下记录认识和搭建Restful规范的技术架构过程(入门级别),在网上发现了一张技术架构图很接近最初想 ...

  8. The Tower of Babylon(UVa 437)

    题意:有n种立方体,每种都有无穷多个.选一些正方体摞成一根尽量高的柱子(可以选择任意一条边做高),使得每个立方体的底面长宽分别严格小于它下方的立方柱的底面长宽. 题解:可以套用DAG最长路算法,可以使 ...

  9. hello1源码解析

    1.选择hello1文件夹并单击“打开项目” 2.展开网页节点,双击index.xhtml文件在编辑器中查看它 index.xhtml文件是facelets应用程序的默认登录页,在典型的facelet ...

  10. 开发中经常遇到SVN清理失败的问题:

    开发中经常遇到SVN清理失败的问题: 解决方法: step1: 到 sqlite官网 https://www.sqlite.org/download.html 下载 sqlite3.exe       ...