@Qualifier作用是在自动按照类型注入的基础上,再按照bean的ID注入,在给类成员注入时,它不能够独立使用,需要配合@Autowired来使用,其中value属性用于指定bean的ID。
@Autowired是根据类型进行自动装配的。如果当Spring上下文中存在不止一个UserDao类型的bean时,就会抛出BeanCreationException异常;如果Spring上下文中不存在UserDao类型的bean,也会抛出BeanCreationException异常。我们可以使用@Qualifier配合@Autowired来解决这些问题。
@Qualifier:限定描述符,用于细粒度选择候选者
- @Autowired默认是根据类型进行注入的,因此如果有多个类型一样的Bean候选者,则需要限定其中一个候选者,否则将抛出异常
- @Qualifier限定描述符除了能根据名字进行注入,更能进行更细粒度的控制如何选择候选者
根据基于XML配置中的<qualifier>标签指定的名字进行注入,使用如下方式指定名称:
-
- 其中type属性可选,指定类型,默认就是Qualifier注解类
- name就是给Bean候选者指定限定标识符
- 一个Bean定义中只允许指定类型不同的<qualifier>,如果有多个相同type后面指定的将覆盖前面的
使用举例:
- 或者:
缺省的根据Bean名字注入:
- 最基本方式,是在Bean上没有指定<qualifier>标签时一种容错机制,即缺省情况下使用Bean标识符注入,
- 但如果你指定了<qualifier>标签将不会发生容错。
例如:(例子中有两个持久层实现类,当在服务层即Service层使用@Autowired注解进行匹配时,变量名称都与持久层定义的bean的ID不相符,此时就可以用@Qualifier注解指定持久层定义的bean的ID!)
spring.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
">
<!--Spring创建容器扫描-->
<context:component-scan base-package="com.hern"/>
<context:annotation-config/>
</beans>
IAccountDao.interface持久层接口
package com.hern.dao;
public interface IAccountDao {
public void saveAccount();
}
IAccountDaoImpl.class持久层第一个实现类
package com.hern.dao;
import org.springframework.stereotype.Repository;
@Repository("IAccountDaoImpl")
public class IAccountDaoImpl implements IAccountDao{
@Override
public void saveAccount() {
System.out.println("持久层实现");
}
}
IAccountDaoImpl2.class持久层第二个实现类
package com.hern.dao;
import org.springframework.stereotype.Repository;
@Repository("IAccountDaoImpl2")
public class IAccountDaoImpl2 implements IAccountDao {
@Override
public void saveAccount() {
System.out.println("持久层实现222");
}
}
IAccountService.interface业务层接口
package com.hern.service;
public interface IAccountService {
/**
* 保存操作
* */
public void saveAccount();
}
IAccountServiceImpl.class类(服务层实现类)
package com.hern.service;
import com.hern.dao.IAccountDao;
import com.hern.dao.IAccountDaoImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("IAccountServiceImpl")
public class IAccountServiceImpl implements IAccountService{
@Autowired
@Qualifier("IAccountDaoImpl2")
private IAccountDao accountDao;
public IAccountServiceImpl() {
System.out.println("IAccountServiceImpl成功实例化");
}
@Override
public void saveAccount() {
accountDao.saveAccount();
}
}
Test.class测试类
package com.hern.util;
import com.hern.service.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test{
/**
* 获取Spring的核心容器,并且根据bean的id获取对象
* */
@SuppressWarnings("all")
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/hern/config/application-spring.xml");
IAccountService iAccountService = (IAccountService) applicationContext.getBean("IAccountServiceImpl");
iAccountService.saveAccount();
}
}
运行效果