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值起为同一名字