Spring 框架並未採用「約定優於配置」的策略,而是要求開發者顯式指定掃描路徑,將符合條件的 Java 類註冊為 Spring Bean。那麼,Spring 如何識別哪些類應作為 Bean 處理?答案在於註解。
Spring 提供四大核心刻板印象註解,分別對應不同架構層級:
最佳實踐:儘量使用 @Controller、@Service、@Repository 替代通用的 @Component,因為未來版本將賦予它們更豐富的語義。Bean 實例默認名稱為類名首字母小寫(如 UserService → userService)。
在 Spring 配置文件中引入 context 命名空間,啟用自動掃描:
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:context="https://www.springframework.org/schema/context"
xsi:schemaLocation="...spring-context-4.0.xsd">
<context:component-scan base-package="org.crazyit.app.service"/>
</beans>
通過 <include-filter> 和 <exclude-filter> 精確控制掃描範圍,支持四種過濾器類型:
| 類型 | 說明 | 示例 |
|---|---|---|
| annotation | 按註解過濾 | lee.AnnotationTest |
| assignable | 按類名過濾 | com.example.MyClass |
| regex | 正則表達式 | org\.example\.default.* |
| aspectj | AspectJ 模式 | org.example..*Service+ |
示例:僅掃描以 Chinese、Axe 結尾的類
<context:component-scan base-package="org.crazyit.app.service">
<context:include-filter type="regex" expression=".*Chinese"/>
<context:include-filter type="regex" expression=".*Axe"/>
</context:component-scan>
@Resource(JSR-250 標準,推薦使用,減少對 Spring 耦合):
@Controller
public class Demo {
@Resource(name="user")
private User user; // Field 注入,無需 Setter
@Resource(name="user")
public void setUser(User user) { this.user = user; }
}
@Autowired(Spring 專有):默認按類型(byType)注入,配合 @Qualifier 按名稱注入。
@Scope 定義 Bean 作用域(singleton、prototype、request、session):
@Controller("demo")
@Scope("prototype")
public class Demo { }
生命周期回調(JSR-250):
@Component
public class Chinese {
@Resource(name="steelAxe")
private SteelAxe steelAxe;
@PostConstruct
public void init() { System.out.println("初始化..."); }
@PreDestroy
public void close() { System.out.println("銷毀前..."); }
}
容器啟動時需註冊關閉鉤子:ctx.registerShutdownHook(); 確保銷毀回調執行。
| 特性 | @Resource | @Autowired |
|---|---|---|
| 來源 | Java EE (JSR-250) | Spring Framework |
| 默認策略 | byName | byType |
| 名稱指定 | name 屬性 | @Qualifier 配合 |
| 推薦度 | ⭐⭐⭐⭐⭐ (標準化) | ⭐⭐⭐⭐ |