早期 Spring 依賴 XML 配置屬性注入,隨著 Spring 2.5+ 引入註解支援,開發效率大幅提升。本文系統梳理 @Autowired、@Resource、@Qualifier、JSR-250 生命週期註解及 <context:annotation-config/> 的用法與最佳實踐。
<bean id="userManagerImpl" class="com.kedacom.service.UserManagerImpl">
<property name="userDao" ref="userDao"/>
</bean>
<bean id="userDao" class="com.kedacom.persistence.UserDaoImpl">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
public class UserManagerImpl implements UserManager {
@Autowired
private UserDao userDao; // Spring 自動按類型匹配唯一 Bean
}
public class UserManagerImpl implements UserManager {
private UserDao userDao;
@Autowired
public void setUserDao(UserDao userDao) { this.userDao = userDao; }
}
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
當容器中存在多個同類型 Bean 時,@Autowired 會拋出 BeanCreationException。使用 @Qualifier 指定 Bean 名稱:
@Autowired
public void setUserDao(@Qualifier("userDao") UserDao userDao) { ... }
允許可選依賴:@Autowired(required = false),找不到 Bean 時不報錯,屬性保持 null。
| 特性 | @Autowired | @Resource |
|---|---|---|
| 來源 | Spring 專有 | JSR-250 標準 |
| 默認策略 | byType | byName |
| 屬性 | required | name, type |
name 和 type:精確匹配唯一 Beanname:按名稱匹配type:按類型匹配唯一 Bean@Resource(name = "userDao")
private UserDao userDao; // 按名稱注入
@Resource(type = UserDao.class)
private UserDao userDao; // 按類型注入
Bean 初始化完成(實例化 + 依賴注入)後調用,典型場景:向父類私有屬性注入值:
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
@Resource
private SessionFactory mySessionFactory;
@PostConstruct
public void injectSessionFactory() {
super.setSessionFactory(mySessionFactory); // 父類 final setter
}
}
Bean 銷毀前調用,用於資源釋放、連接關閉等清理工作,用法同 @PostConstruct。
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:context="https://www.springframework.org/schema/context"
xsi:schemaLocation="...
https://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
隱式註冊 4 個後處理器:
AutowiredAnnotationBeanPostProcessor:處理 @Autowired/@QualifierCommonAnnotationBeanPostProcessor:處理 @Resource/@PostConstruct/@PreDestroyPersistenceAnnotationBeanPostProcessor:處理 @PersistenceContext/@PersistenceUnitRequiredAnnotationBeanPostProcessor:處理 @Required@Autowired(單構造器可省略)。