ComponentScan註解的掃描範圍及源碼解析
一,ComponentScan註解的默認掃描範圍
ComponentScan註解的默認掃描範圍是啓動程序XxxApplication. java所在目錄及其下的所有子包。
爲了方便理解,我們看一下下面這個圖片。
這個項目中的啓動類是:SpringbootApplication.java
該啓動類所在的目錄是:springboot
那麼ComponentScan註解的默認掃描範圍是:springboot目錄及其下面的所有子包。
二,如何修改ComponentScan註解的掃描範圍
ComponentScan註解即可以掃描包,也可以掃描指定的類。我們只需要指定一個包掃描的路徑,就可以實現更改包掃描路徑的功能了。
1,ComponentScan註解掃描包。
@ComponentScan({"com.company.user","com.company.service"})
2,ComponentScan註解掃描類。
@ComponentScan(basePackageClasses={XxxService.class})
三,ComponentScan註解
ComponentScan註解中定義了12個屬性,我們下面詳細來看一下。我們的討論是基於java8的,spring-context的版本是4.3.7。
1,String[] value() default {};
指定包掃描路徑,value屬性的值,就是項目中的一個具體路徑。value屬性的類型是String數組,也就是支持一次指定多個包掃描路徑。這個屬性上面添加了一個註解,@AliasFor("basePackages"),這個註解的意思就是說,value這個屬性等價於basePackages屬性。關於basePackages屬性,下面會講到。
2,String[] basePackages() default {};
指定包掃描路徑,basePackages屬性的值,就是項目中的一個具體路徑。basePackages屬性的類型是String數組,也就是支持一次指定多個包掃描路徑。basePackages屬性上面添加了一個註解,@AliasFor("value"),這個註解的意思就是說,basePackages這個屬性等價於value屬性。
3,Class<?>[] basePackagesClasses() default {};
掃描具體的類。basePackagesClasses屬性的類型是Class數組,也就是說支持同時指定多個掃描類。
4,Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator. class;
配置beanName生成器,默認是BeanNameGenerator。一般情況下,我們都是使用默認的beanName生成器,但是Spring實現了beanName生成器的可配置。
5,Class<? extends ScopeMetaDataResolver> scopeResolver() default AnnotationScopeMetaDataResolver.class;
處理檢測到的bean的scope範圍。什麼意思呢?我們都知道spring的bean是有作用域的,默認是singleton,這個默認值就是在ScopeMetaData類中指定的:
private String scopeName = "singleton";
這個屬性也是可選配置,默認的處理bean作用域的實現類是AnnotationScopeMetaDataResolver.class。源碼比較簡單,就是取註解上獲取指定的scope的value值,如果沒有配置,就是用默認的singleton。
6,ScopedProxyMode scopedProxy() default ScopedProxyMode. DEFAULT;
是否爲檢測到的組件生產代理。
ScopedProxyMode是一個枚舉類,可選值有四個:DEFAULT,NO,INTERFACES,TARGET_CLASS。
7,String resourcePattern() default """**/*.class";
控制符合組件檢測條件的類文件,默認是包掃描下的 **/*.class。
8,boolean useDefaultFilters() default true;
是否對含有以下註解的類開啓檢測,默認是開啓的。
@Component
@Repository
@Service
@Controller
9,ComponentScan.Filter[] includeFilters() default {};
指定某些Filter掃描到的類。聽起來有些費勁,說白了就是指定了類型,掃描指定的這些類型。可選類型有5種,定義在枚舉類FilterType中:
第一種:ANNOTATION
第二種:ASSIGNABLE_TYPE
第三種:ASPECTJ
第四種:REGEX,正則表達式。
第五種:CUSTOM,自定義類型。
10,ComponentScan.Filter[] excludeFilters() default {};
排除過濾器掃描的的類。
11,boolean lazyInit() default false;
掃描到的類是否開啓懶加載,默認不開啓。
12,
@Retention(RetentionPolicy.RUNTIME);
@Target({})
public @interface Filter {
FilterType type() default FilterType. ANNOTATION;
@AliasFor("classes")
Class<?>[] value() default {};
@AliasFor("value")
Class<?>[] classes() default {};
String[] pattern() default {};
}
ComponentScan的內部接口,主要是對Filter的封裝。