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