目录
@Component、@Repository、@Service、 @Controller
案例3:ComponentScan通过basePackageClasses指定扫描范围
背景介绍
到目前为止,介绍了2种注册bean的方式:
- xml中bean元素的方式
- @Bean注解标注方法的方式
通常情况下,项目中大部分类都需要交给spring去管理,按照上面这2种方式,代码量还是挺大的。 为了更方便bean的注册,Spring提供了批量的方式注册bean,方便大量bean批量注册,spring中的 @ComponentScan就是干这个事情的。
@ComponentScan
@ComponentScan注解用于批量注册bean
这个注解会让spring去扫描某些包及其子包中所有的类,然后将满足一定条件的类作为bean注册到 spring容器容器中。 具体需要扫描哪些包?以及这些包中的类满足什么条件时被注册到容器中,这些都可以通过这个注解中的参数动态配置。
先来看一下这个注解的源码:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
boolean useDefaultFilters() default true;
Filter[] includeFilters() default {};
Filter[] excludeFilters() default {};
boolean lazyInit() default false;
- @Repeatable(ComponentScans.class):表示@ComponentScan可以重复使用
- value:指定扫描的包
- basePackages:和value参数一样,都是不能同时使用,二选一
- basePackageClasses:指定扫描该类所在的包以及子包,注意并不是只扫描该类
- nameGenerator:自定义bean名称生成器
- resourcePattern:需要扫描包中的那些资源,默认是:**/*.class,即会扫描指定包中所有的 class文件
- userDefaultFilters:指定是否应启用使用@Component,@Repository ,@Service或@Controller注释的类的自动检测,默认为true
- includeFilters:过滤器:用来配置被扫描出来的那些类会被作为组件注册到容器中
- excludeFilters:过滤器,和includeFilters作用刚好相反,用来对扫描的类进行排除的,被排除的类不会被注册到容器中
- lazyInit:是否延迟初始化被注册的bean,默认为false
@ComponentScan工作的过程:
- Spring会扫描指定的包,且会递归下面子包,得到一批类的数组
- 然后这些类会经过上面的各种过滤器,最后剩下的类会被注册到容器中
所以玩这个注解,主要关注2个问题:
- 需要扫描哪些包?通过 value、backPackages、basePackageClasses 这3个参数来控制
- 过滤器有哪些?通过 useDefaultFilters、includeFilters、excludeFilters 这3个参数来控制过滤器
这两个问题搞清楚了,就可以确定哪些类会被注册到容器中。
默认情况下,任何参数都不设置的情况下,此时,会将@ComponentScan修饰的类所在的包作为扫描包;默认情况下useDefaultFilters为true,这个为true的时候,spring容器内部会使用默认过滤器,规则是:凡是类上有@Repository、@Service、@Controller、@Component 这四个注解中的任何一个的,那么这个类就会被作为bean注册到spring容器中,所以默认情况下,只需在类上加上这几个注解中的任何一个,这些类就会自动交给spring容器来管理了。
@Component、@Repository、@Service、 @Controller
这几个注解都是spring提供的
我们先来看一下&#