Spring 2.5 引入豐富的註解支援,標誌著配置方式從冗長的 XML 向類內聚、零配置演進。註解配置利用 Java 反射機制自動推導元數據,減少樣板代碼;將配置與業務邏輯共存同一檔案,增強內聚性;並提供 @Autowired、@Resource、@Component 等核心註解,實現依賴注入與 Bean 定義的全註解化。
<bean id="boss" class="com.baobaotao.Boss">
<property name="car" ref="car"/>
<property name="office" ref="office"/>
</bean>
<bean id="office" class="com.baobaotao.Office">
<property name="officeNo" value="002"/>
</bean>
<bean id="car" class="com.baobaotao.Car" scope="singleton">
<property name="brand" value="紅旗 CA72"/>
<property name="price" value="2000"/>
</bean>
可標註於欄位、Setter、建構子,預設 byType 匹配:
// 欄位注入 (推薦:簡潔、不可變、易測試)
@Autowired
private Car car;
@Autowired
private Office office;
// Setter 注入
@Autowired
public void setCar(Car car) { this.car = car; }
// 建構子注入 (Spring 4.3+ 單建構子可省略 @Autowired)
@Autowired
public Boss(Car car, Office office) {
this.car = car;
this.office = office;
}
啟用條件:需在 Spring 容器註冊 AutowiredAnnotationBeanPostProcessor,或使用 <context:annotation-config/>。
當同類型 Bean >1 時,配合 @Autowired 指定 Bean 名稱,策略轉為 byName:
@Autowired
@Qualifier("office")
private Office office;
// 建構子參數
@Autowired
public Boss(Car car, @Qualifier("office") Office office) { ... }
預設 byName,屬性 name 指定 Bean 名稱,type 指定類型:
@Resource // byName: 欄位名 "car" 對應 bean name "car"
private Car car;
@Resource(name = "office") // 明確指定 bean name
private Office office;
啟用條件:需註冊 CommonAnnotationBeanPostProcessor 或 <context:annotation-config/>。
替代 init-method/destroy-method,支援多方法標註:
@PostConstruct
public void initCache() { ... }
@PostConstruct
public void warmUp() { ... } // 多個初始化方法皆會執行
@PreDestroy
public void cleanup() { ... }
替代 <bean> 宣告,掃描機制自動發現:
@Component("boss") // 可選名稱,預設類名首字母小寫
public class Boss { ... }
@Service // 業務層語義
public class UserService { ... }
@Repository // 持久層語義,自動轉換 DataAccessException
public class UserDao { ... }
@Controller // 控制層語義
public class UserController { ... }
<?xml version="1.0" encoding="UTF-8"?>
<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-2.5.xsd">
<!-- 掃描基礎包,遞歸子包,隱式註冊 4 個 BeanPostProcessor -->
<context:component-scan base-package="com.baobaotao"/>
<!-- 進階過濾範例 -->
<context:component-scan base-package="com.baobaotao">
<context:include-filter type="regex" expression="com\.baobaotao\.service\..*"/>
<context:exclude-filter type="aspectj" expression="com.baobaotao.util..*"/>
</context:component-scan>
</beans>
過濾器類型:annotation、assignable (類名)、regex、aspectj
@Scope("prototype")
@Component("boss")
public class Boss { ... } // 每次 getBean 返回新實例
| 場景 | 推薦方式 | 理由 |
|---|---|---|
| 自有類別、依賴固定不變 | 註解 | 內聚性高、無需重編譯調整 |
| 第三方類 (DataSource, SessionFactory) | XML | 無法修改源碼加註解 |
| 部署環境差異化配置 (JNDI 名稱、連接池參數) | XML | 外部化配置、無需重打包 |
| 複雜 AOP/事務切點表達式 | XML (aop/tx ns) | 表達力更強、可讀性更好 |
| 屬性檔案佔位符解析 | XML + <context:property-placeholder> | 標準化外部化配置 |
@Service、DAO 層用 @Repository、Controller 用 @Controller、通用組件用 @Component@Lazy/Setter 注入緩解@Configuration 類替代完整掃描Spring 註解驅動 IoC 不只是語法糖,更是推動「配置即代碼、約定優於配置」工程文化的關鍵里程碑。合理混用註解與 XML,才能兼得開發效率與部署靈活性。