@Qualifier
- 按类型自动装配可能多个bean实例的情况,可以使用Spring的@Qualifier注解缩小范围(或指定唯一),也可以用于指定单独的构造器参数或方法参数
- 可用于注解集合类型变量
- 如果通过名字进行注解注入,主要使用的不是@Autowired(即使在技术上能够通过@Qualifier指定bean的名字),替代方式是使用JSP-250标准中的@Resource注解,它是通过其独特的名称来定义来识别特定的目标(这是一个与所声明的类型是无关的匹配过程)
- 因语义差异,集合或Map类型的bean无法通过@Autowired来注入,因为没有类型匹配到这样的bean,为这些bean使用@Resource注解,通过唯一名称引用集合或Map的bean
- @Autowired适用于fields,constructors,multi-argumentmethods这些允许在参数级别使用@Qualifier注解缩小范围的情况
- @Resource适用于成员变量、只有一个参数的setter方法,所以在目标是构造器或一个多参数方式时,最后的方式时使用qualifiers
@Qualifier例子:
pom.xml
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.14.RELEASE</version>
</dependency>
spring-beanannotation.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.torey.beanannotation"/>
</beans>
package com.torey.beanannotation.multibean;
/**
* @InterfaceName:BeanInterface 用途:
* 作者: litaofeng
* 时间: 2019/8/25 22:22
*/
public interface BeanInterface {
}
package com.torey.beanannotation.multibean;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* @ClassName:BeanInterfaceOne
* @Description:
* @author: Torey
*/
@Component
public class BeanImplOne implements BeanInterface {
}
package com.torey.beanannotation.multibean;
import org.springframework.stereotype.Component;
/**
* @ClassName:BeanInterfaceTwo
* @Description:
* @author: Torey
*/
@Component
public class BeanImplTwo implements BeanInterface {
}
package com.torey.beanannotation.multibean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
/**
* @ClassName:BeanInvoker
* @Description:Qualifier演示,可以缩小实现类的范围
* @author: Torey
*/
@Component
public class BeanInvoker {
@Autowired
@Qualifier("beanImplOne")
private BeanInterface oneBeanInterface;
@Autowired
@Qualifier("beanImplTwo")
private BeanInterface twoBeanInterface;
public void say(){
if (null!=oneBeanInterface) {
System.out.println(oneBeanInterface.getClass().getName());
}else {
System.out.println("oneBeanInterface is null");
}
if (null!=twoBeanInterface) {
System.out.println(twoBeanInterface.getClass().getName());
}else {
System.out.println("twoBeanInterface is null");
}
}
}
package com.torey.springtest.base;
import org.junit.After;
import org.junit.Before;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.StringUtils;
/**
* @ClassName:UnitTestBase
* @Description:
* @author: Torey
*/
public class UnitTestBase {
public UnitTestBase(){}
private String springXmlPath;
private ClassPathXmlApplicationContext applicationContext;
public UnitTestBase(String springXmlpath){
this.springXmlPath=springXmlpath;
}
@Before
public void before(){
if (StringUtils.isEmpty(springXmlPath)) {
springXmlPath="classpath*:spring-*.xml";
}
applicationContext= new ClassPathXmlApplicationContext(springXmlPath.split("[,\\s]"));
applicationContext.start();
}
@After
public void after(){
applicationContext.destroy();
}
public Object getBean(String beanId){
return applicationContext.getBean(beanId);
}
}
package com.torey.springtest.bean;
import com.torey.beanannotation.multibean.BeanInvoker;
import com.torey.springtest.base.UnitTestBase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
/**
* @ClassName:TestResource
* @Description:
* @author: Torey
*/
@RunWith(BlockJUnit4ClassRunner.class)
public class TestBeanAnnotation extends UnitTestBase {
public TestBeanAnnotation(){
super("classpath:spring-beanannotation.xml");
}
@Test
public void testMultBean(){
BeanInvoker invoker= (BeanInvoker) super.getBean("beanInvoker");
invoker.say();
}
}