用於指定包的掃描路徑。用於代替spring的xml配置文件中的<context:componet-scan base-package=""/>
標籤。java
context:componet-scan
標籤context:componet-scan
的做用spring就會去自動掃描base-package對應的路徑或者該路徑的子包下面的帶有@Service
,@Component
,@Repository
,@Controller
註解的java文件。正則表達式
context:componet-scan
屬性base-package
: 指定掃描路徑。use-default-filters
: 是否使用默認的掃描過濾器。use-default-filters=true
表示掃描包路徑的@Service
,@Component
,@Repository
,@Controller
註解的類;若是你不想所有掃描這些類,能夠進行過濾,好比說你不想掃描@Controller
註解的類。<context:componet-scan base-package="com.sff.app" use-default-filters="true"> <!--不掃描@Controller註解的類--> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:componet-scan>
<context:componet-scan base-package="com.sff.app" use-default-filters="false"> <!--只掃描@Controller註解的類--> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:componet-scan>
use-default-filters=true
表示按照自定義規則掃描包路徑下的類;該註解是使用在咱們的配置類上的。spring
/** * 配置類等價於spring的配置文件 */ @Configuration @ComponentScan(value = "com.sff.app", includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class)}, useDefaultFilters = false) public class AppConfig { /*給容器中註冊一個bean,類型是方法返回值,id就是方法名稱*/ @Bean public Person person() { return new Person("Kate", 12); } }
@ComponentScan(value = "com.sff.app",useDefaultFilters = false, excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class})}) @ComponentScan(value = "com.sff.app", excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class})})
use-default-filters
的功能。咱們看下註解源碼是怎麼定義的?express
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @Repeatable(ComponentScans.class) public @interface ComponentScan { /*定義了包掃描路徑屬性*/ @AliasFor("basePackages") String[] value() default {}; @AliasFor("value") String[] basePackages() default {}; /*默認使用默認的過濾,所有掃描*/ boolean useDefaultFilters() default true; /*過濾器屬性,過濾器是一個數組,能夠配置多個*/ ComponentScan.Filter[] includeFilters() default {}; ComponentScan.Filter[] excludeFilters() default {}; /*過濾器註解*/ @Retention(RetentionPolicy.RUNTIME) @Target({}) public @interface Filter { /*默認的過濾規則是按照註解來過濾*/ FilterType type() default FilterType.ANNOTATION; } } /*Filter中的FilterType支持過濾類型*/ public enum FilterType { ANNOTATION, //註解 ASSIGNABLE_TYPE, //指定類型,好比指定包路徑下的某個具體類 ASPECTJ,//使用aspectj表達式 REGEX,//正則表達式 CUSTOM;//自定義 }
/** * 自定義過濾規則 */ public class CustomFilterType implements TypeFilter { /** * @param metadataReader 獲取當前正在掃描的類的信息 * @param metadataReaderFactory 獲取其餘類的信息 * @return * @throws IOException */ @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { /*獲取當前類的註解信息*/ AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); /*獲取當前類的信息*/ ClassMetadata classMetadata = metadataReader.getClassMetadata(); /*獲取資源文件*/ Resource resource = metadataReader.getResource(); System.out.println("---------------->" + classMetadata.getClassName()); /*過濾類全名稱包括HelloController的類*/ if (classMetadata.getClassName().contains("HelloController")) { return true; } return false; } }
/** * 配置類等價於spring的配置文件 */ @Configuration @ComponentScan(value = "com.sff.app",useDefaultFilters = false, includeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM, classes = CustomFilterType.class)}) public class AppConfig { /*給容器中註冊一個bean,類型是方法返回值,id就是方法名稱*/ @Bean public Person person() { return new Person("Kate", 12); } }
public class ComponentScanTest { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); String[] names = ctx.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } } }
結果分析:數組
//打印出了當前掃描的類的信息 ---------------->com.sff.app.ComponentScanTest ---------------->com.sff.app.ConfigurationTest ---------------->com.sff.app.TestAnno ---------------->com.sff.app.anno.AnnoDemo ---------------->com.sff.app.anno.MyAnnotation ---------------->com.sff.app.anno.Rename ---------------->com.sff.app.bean.Person ---------------->com.sff.app.config.CustomFilterType ---------------->com.sff.app.controller.HelloController ---------------->com.sff.app.service.HelloService org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalRequiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory /*過濾後容器中的類信息*/ appConfig //主配置類 helloController person //經過@Bean注入的