欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring框架中@Qualifier()标签的使用及UnsatisfiedDependencyException和NoSuchBeanDefinitionException产生的原因

程序员文章站 2022-04-30 20:00:06
...

Spring框架中@Qualifier()标签的使用

以Spring框架配置文件的QueryRunner为例,配置文件中QueryRunner的id为queryRunner

<bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
    <constructor-arg name="ds" ref="dataSource"></constructor-arg>
</bean>

dao层的实现类对象需要QueryRunner对象,将QueryRunner向上抽取到成员位置,并交给spring管理
标签解读:
@AutoWired,按类型注入(Spring提供),如果按类型无法唯一的定位对象,那么就需要结合@Qualifier一起使用(只声明属性即可,不需要setXXX方法)
@Resource,按id注入(JDK提供),参数指定bean的id
为了更好的区分@Resource,按id注入
配置文件中QueryRunner的id值,取为queryRunner
dao层的实现类对象中QueryRunner对象的名字取为qr;

dao层接口的实现类对象

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Autowired
    @Qualifier("queryRunner")
    //错误理解 @Qualifier("qr")
    private QueryRunner qr;

    @Override
    public List<User> queryAll() throws Exception {
        String sql="select * from user";
        return qr.query(sql,new BeanListHandler<>(User.class));
    }
}

dao层接口

public interface UserDao {
    //查询所有
    List<User> queryAll() throws Exception;
}

service层的接口

public interface UserService {
    //查询所有
    List<User> queryAll() throws Exception;
}

service层的实现类对象

@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
@Qualifier("userDao")
private UserDao userDao;
    @Override
    public List<User> queryAll() throws Exception {
        List<User> users = userDao.queryAll();
        return users;
    }
}

测试代码

   @Test
   public void text01() throws Exception {
      ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applictionContext.xml");
      UserServiceImpl userService = context.getBean("userService", UserServiceImpl.class);
      List<User> users = userService.queryAll();
      users.forEach(System.out::println);
   }

如果用错误的@Qualifier(“qr”)注解,配置文件中运行,异常的主要信息为:UnsatisfiedDependencyException和NoSuchBeanDefinitionException

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userDao': Unsatisfied dependency expressed through field 'qr'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.apache.commons.dbutils.QueryRunner' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=qr)}
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.apache.commons.dbutils.QueryRunner' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=qr)}
如果将配置文件中bean id="queryRunner"改为<bean id="qr">,dao层使用 @Qualifier("qr"),就可以正常编译运行
配置文件中<bean id="queryRunner">,dao层使用 @Qualifier("qr"),则编译失败
配置文件中<bean id="queryRunner">,dao层使用 @Qualifier("queryRunner"),可以正常编译运行

通过代码测试发现,@Qualifier()标签中传递的是对应bean标签的id值.
与dao层实现类对象中成员位置上 QueryRunner对象的变量名无关,
验证了@Resource(),按id注入(JDK提供),参数指定bean的id
为了以后不混淆,建议将对象的变量名与标签的id值起为同一名字