/*
* @since 3.1
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
/**
* Alias for {@link #basePackages}.
* <p>Allows for more concise annotation declarations if no other attributes
* are needed — for example, {@code @ComponentScan("org.my.pkg")}
* instead of {@code @ComponentScan(basePackages = "org.my.pkg")}.
*/
@AliasFor("basePackages")
String[] value() default {};
/**
* Base packages to scan for annotated components.
* <p>{@link #value} is an alias for (and mutually exclusive with) this
* attribute.
* <p>Use {@link #basePackageClasses} for a type-safe alternative to
* String-based package names.
*/
@AliasFor("value")
String[] basePackages() default {};
/**
* Indicates whether automatic detection of classes annotated with {@code @Component}
* {@code @Repository}, {@code @Service}, or {@code @Controller} should be enabled.
*/
boolean useDefaultFilters() default true;
/**
* Specifies which types are eligible for component scanning.
* <p>Further narrows the set of candidate components from everything in {@link #basePackages}
* to everything in the base packages that matches the given filter or filters.
* <p>Note that these filters will be applied in addition to the default filters, if specified.
* Any type under the specified base packages which matches a given filter will be included,
* even if it does not match the default filters (i.e. is not annotated with {@code @Component}).
* @see #resourcePattern()
* @see #useDefaultFilters()
*/
Filter[] includeFilters() default {};
/**
* Specifies which types are not eligible for component scanning.
* @see #resourcePattern
*/
Filter[] excludeFilters() default {};
/**
* Declares the type filter to be used as an {@linkplain ComponentScan#includeFilters
* include filter} or {@linkplain ComponentScan#excludeFilters exclude filter}.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({})
@interface Filter {
/**
* The type of filter to use.
* <p>Default is {@link FilterType#ANNOTATION}.
* @see #classes
* @see #pattern
*/
FilterType type() default FilterType.ANNOTATION;
/**
* Alias for {@link #classes}.
* @see #classes
*/
@AliasFor("classes")
Class<?>[] value() default {};
/**
* The class or classes to use as the filter.
* <p>The following table explains how the classes will be interpreted
* based on the configured value of the {@link #type} attribute.
* <table border="1">
* <tr><th>{@code FilterType}</th><th>Class Interpreted As</th></tr>
* <tr><td>{@link FilterType#ANNOTATION ANNOTATION}</td>
* <td>the annotation itself</td></tr>
* <tr><td>{@link FilterType#ASSIGNABLE_TYPE ASSIGNABLE_TYPE}</td>
* <td>the type that detected components should be assignable to</td></tr>
* <tr><td>{@link FilterType#CUSTOM CUSTOM}</td>
* <td>an implementation of {@link TypeFilter}</td></tr>
* </table>
* <p>When multiple classes are specified, <em>OR</em> logic is applied
* — for example, "include types annotated with {@code @Foo} OR {@code @Bar}".
* <p>Custom {@link TypeFilter TypeFilters} may optionally implement any of the
* following {@link org.springframework.beans.factory.Aware Aware} interfaces, and
* their respective methods will be called prior to {@link TypeFilter#match match}:
* <ul>
* <li>{@link org.springframework.context.EnvironmentAware EnvironmentAware}</li>
* <li>{@link org.springframework.beans.factory.BeanFactoryAware BeanFactoryAware}
* <li>{@link org.springframework.beans.factory.BeanClassLoaderAware BeanClassLoaderAware}
* <li>{@link org.springframework.context.ResourceLoaderAware ResourceLoaderAware}
* </ul>
* <p>Specifying zero classes is permitted but will have no effect on component
* scanning.
* @since 4.2
* @see #value
* @see #type
*/
@AliasFor("value")
Class<?>[] classes() default {};
}
}
解读@ComponentScan
@ComponentScan表示给带有@Configuration的类配置一个组件扫描指令。
-
支持与Spring XML’s context:component-scan element 并行使用。
-
可以使用basePackageClasses, basePackages或者value属性来指定已经定义的包目录,
从而纳入到扫描范围内。
-
如果指定的包并不是一个正确的已定义的包,那么将从
使用@ComponentScan注解的类所在包开始扫描。 -
但如果没有为value或者basePackages配置值,那么将从
使用@ComponentScan注解的类所在包及其子包开始扫描。【这也就是为什么 @SpringBootApplication 内部的 @ComponentScan 没有指定具体的
包,也能够从启动类所在包及其子包扫描到组件的原因】
-
特别的,由 @ComponentScan 上的 @Repeatable(ComponentScans.class) 我们可以进
一步得知 @ComponentScan 是可以重复使用的。
这就与在xml中,多次使用 context:component-scan 的效果相同。
-
需要注意的是,在 context:component-scan element 有 annotation-config 属性,
但 annotation-config 在 @ComponentScan 中是不存在的。
这是因为在大多数使用 @ComponentScan的场景下,我们总是假定使用默认annotation
config处理。
此外,当我们使用AnnotationConfigApplicationContext的时候,annotation config
processors 总是会进行注册。
这也就意味着任何尝试在 @ComponentScan 上禁用它们的操作将会被忽略。
-
如果单独使用 @ComponentScan,即便配置上basePackages值,也不会对指定的包进行扫描,需要和@Configuration进行组合使用。
-
仅仅将一个类配上@Component是不会自动注册到容器里的,还得需要@ComponentScan。
-
@Configuration
new AnnotationConfigApplicationContext(ThirdConfig.class) /** * 创建一个AnnotationConfigApplicationContext对象,从给定的component classes得到bean的定义并且会自动刷新上下文 * <p/> * Create a new AnnotationConfigApplicationContext, deriving bean definitions * from the given component classes and automatically refreshing the context. * <p/> * @param componentClasses one or more component classes - for example, @Configuration classes */ public AnnotationConfigApplicationContext(Class<?>... componentClasses) { this(); // Register one or more component classes to be processed. register(componentClasses); refresh(); }
解读FilterType
/**
* Enumeration of the type filters that may be used in conjunction with
* {@link ComponentScan @ComponentScan}.
*
* @since 2.5
* @see ComponentScan
* @see ComponentScan#includeFilters()
* @see ComponentScan#excludeFilters()
* @see org.springframework.core.type.filter.TypeFilter
*/
public enum FilterType {
/**
* Filter candidates marked with a given annotation.
* @see org.springframework.core.type.filter.AnnotationTypeFilter
*/
ANNOTATION,
/**
* Filter candidates assignable to a given type.
* @see org.springframework.core.type.filter.AssignableTypeFilter
*/
ASSIGNABLE_TYPE,
/**
* Filter candidates matching a given AspectJ type pattern expression.
* @see org.springframework.core.type.filter.AspectJTypeFilter
*/
ASPECTJ,
/**
* Filter candidates matching a given regex pattern.
* @see org.springframework.core.type.filter.RegexPatternTypeFilter
*/
REGEX,
/** Filter candidates using a given custom
* {@link org.springframework.core.type.filter.TypeFilter} implementation.
*/
CUSTOM
}
-
Filter,声明类型过滤器,该过滤器将会作为 include filter or exclude filter 来使用。
-
includeFilters,(指定扫描的时候只包含哪些组件)
进一步将候选组件从 basePackages 全部范围内缩小到只有在 basePackages 范围内匹配给定 filter or filters 才能包含。
需要注意的是,如果指定了有includeFilters,那么除了默认的过滤器,这些includeFilters也会应用进来。
在指定basePackages下的任何类型只要是能够匹配到给定的filter就会包含进来
尽管它并没有匹配到default filters(也就是没有标识 @Component 注解) -
excludeFilters,(指定扫描的时候按照什么规则排除哪些组件)
-
useDefaultFilters,表示是否自动检测标注有 @Component @Repository, @Service, or @Controller 的类
-
FilterType,过滤器类型,枚举类
- FilterType#ANNOTATION,按照注解的形式
- FilterType#ASSIGNABLE_TYPE,按照给定的类型
- FilterType#ASPECTJ,使用ASPECTJ表达式的形式
- FilterType#REGEX,使用正则表达式
- FilterType#CUSTOM,使用给定的自定义过滤器,需要实现TypeFilter接口

本文深入解读了Spring框架中的@ComponentScan注解,解释了其用于组件扫描的配置,包括basePackageClasses、basePackages或value属性的指定,以及如何与@Configuration结合使用。同时,讨论了FilterType在@ComponentScan中的作用,如includeFilters和excludeFilters的过滤规则,以及FilterType的几种类型,如ANNOTATION、ASSIGNABLE_TYPE、ASPECTJ、REGEX和CUSTOM。
431

被折叠的 条评论
为什么被折叠?



