@Qualifier作用是在自动按照类型注入的基础上,再按照bean的ID注入,在给类成员注入时,它不能够独立使用,需要配合@Autowired来使用,其中value属性用于指定bean的ID。

@Autowired是根据类型进行自动装配的。如果当Spring上下文中存在不止一个UserDao类型的bean时,就会抛出BeanCreationException异常;如果Spring上下文中不存在UserDao类型的bean,也会抛出BeanCreationException异常。我们可以使用@Qualifier配合@Autowired来解决这些问题。

@Qualifier:限定描述符,用于细粒度选择候选者

  • @Autowired默认是根据类型进行注入的,因此如果有多个类型一样的Bean候选者,则需要限定其中一个候选者,否则将抛出异常
  • @Qualifier限定描述符除了能根据名字进行注入,更能进行更细粒度的控制如何选择候选者
    • Spring @Qualifier注解_其他

根据基于XML配置中的<qualifier>标签指定的名字进行注入,使用如下方式指定名称:

  • Spring @Qualifier注解_持久层_02
    • 其中type属性可选,指定类型,默认就是Qualifier注解类
    • name就是给Bean候选者指定限定标识符
    • 一个Bean定义中只允许指定类型不同的<qualifier>,如果有多个相同type后面指定的将覆盖前面的

使用举例:

Spring @Qualifier注解_spring_03

  • 或者:

Spring @Qualifier注解_xml_04

缺省的根据Bean名字注入

  • 最基本方式,是在Bean上没有指定<qualifier>标签时一种容错机制,即缺省情况下使用Bean标识符注入,
  • 但如果你指定了<qualifier>标签将不会发生容错。

例如:(例子中有两个持久层实现类,当在服务层即Service层使用@Autowired注解进行匹配时,变量名称都与持久层定义的bean的ID不相符,此时就可以用@Qualifier注解指定持久层定义的bean的ID!)

Spring @Qualifier注解_其他_05

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();
    }
}

运行效果

Spring @Qualifier注解_xml_06