@ComponentScan
用于指定包的扫描路径。用于代替spring的xml配置文件中的<context:componet-scan base-package=""/>
标签。
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
表示按照自定义规则扫描包路径下的类;
@ComponentScan的使用
该注解是使用在我们的配置类上的。
/**
* 配置类等价于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的属性说明
@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})})
- useDefaultFilters: 是否使用默认的扫描过滤器,相当于
use-default-filters
的功能。 - excludeFilters: 指定扫描时需要按照什么规则排除不扫描的类。
- includeFilters: 指定扫描时需要按照什么规则扫描的类。
我们看下注解源码是怎么定义的?
@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;//自定义
}
@ComponentScan的自定义扫描规则
- 实现TypeFilter类
/**
* 自定义过滤规则
*/
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注入的