相信接觸過spring做開發的小夥伴們一定使用過@ComponentScan註解
@ComponentScan("com.wangm.lifecycle")
public class AppConfig {
}
@ComponentScan指定basePackage,將包下的類按照一定規則註冊成Bean。
但是這個註解的其他引數,比如excludeFilters、includeFilters以及底層掃描的實現你有沒有了解過?
1. 預設的掃描規則
當我們使用@ComponentScan沒有指定excludeFilters、includeFilters時,basePackage下哪些類會被掃描成Bean呢?
相信大家一定知道是攜帶了@Component,@Service等等註解的類,那麼這個預設的規則在spring的原始碼中是如何實現的呢?
@ComponentScan掃描包主要是透過ClassPathBeanDefinitionScanner
這個類來實現的;
在構造方法ClassPathBeanDefinitionScanner#ClassPathBeanDefinitionScanner()
中
指定了預設的過濾規則->
預設的規則:
- 攜帶@Component註解
- Java滿足指定版本是,攜帶@ManagedBean註解
- Java滿足指定版本是,攜帶@Named註解
2.掃描的實現
我們再來看ClassPathBeanDefinitionScanner
類的關鍵方法doScan()
doScan()
方法的核心是scanCandidateComponents
方法
我們點進isCandidateComponent
方法接著看
- 第一個判斷:如果滿足排除條件,則不生成Bean,這個比較好理解
- 第二個判斷:如果滿足包含條件,並沒有直接返回true,而是還要滿足
isConditionMatch
isConditionMatch
方法就是@Conditional註解的實現