SpringBoot - @ComponentScan注解使用详解

写在前面

SpringBoot - @Configuration注解使用详解
SpringBoot - 向容器中注册组件的方法有哪些?
SpringBoot - 如何查看Spring上下文中加载的Bean

@ComponentScan注解的作用是什么?

@ComponentScan主要用于将指定包路径下的、带有特定注解的对象自动装配到Spring容器中。ComponentScan会把正确标注@Component注解的对象进行自动装配。除了@Component外,还有@Controller、@Repository、@Service也标注了@Component注解。
简单来讲:在Spring中通过定义bean的注解定义了一些bean,而Spring并不知道除非你告诉它去可以找到它们,而@ComponentScan的作用就是告诉Spring去哪个路径下可以找到这些bean。

@ComponentScan注解如何使用?

@ComponentScan注解可以定义在接口、类、枚举、注解上。有以下几个常用属性:

  • [1] basePackages:定义待扫描的包路径名
  • [2] basePackageClasses:定义待扫描的类名
  • [3] includeFilters: 满足过滤器条件的,才能被扫描
  • [4] excludeFilters:满足过滤器条件的,不会被扫描

注意:includeFilters和excludeFilters都需要借助@ComponentScan.Filter来完成相应的扫描规则,FilterType有以下几个可选项:

  • [1] ANNOTATION(默认注解类型)
  • [2] ASSIGNABLE_TYPE(指定固定类)
  • [3] ASPECTJ(ASPECTJ类型)
  • [4] REGEX(正则表达式)
  • [5] CUSTOM(自定义类型),自定义的Filter需要实现TypeFilter接口
@ComponentScan(
    includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Service.class})},
    excludeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM, classes = MyExcludeFilter.class)}
)

@ComponentScan源码分析

@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 {};

	/**
	 * The {@link BeanNameGenerator} class to be used for naming detected components
	 * within the Spring container.
	 * <p>The default value of the {@link BeanNameGenerator} interface itself indicates
	 * that the scanner used to process this {@code @ComponentScan} annotation should
	 * use its inherited bean name generator, e.g. the default
	 * {@link AnnotationBeanNameGenerator} or any custom instance supplied to the
	 * application context at bootstrap time.
	 * @see AnnotationConfigApplicationContext#setBeanNameGenerator(BeanNameGenerator)
	 * @see AnnotationBeanNameGenerator
	 * @see FullyQualifiedAnnotationBeanNameGenerator
	 */
	Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
	/**
	 * The {@link ScopeMetadataResolver} to be used for resolving the scope of detected components.
	 */
	Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
		/**
	 * Indicates whether proxies should be generated for detected components, which may be
	 * necessary when using scopes in a proxy-style fashion.
	 * <p>The default is defer to the default behavior of the component scanner used to
	 * execute the actual scan.
	 * <p>Note that setting this attribute overrides any value set for {@link #scopeResolver}.
	 * @see ClassPathBeanDefinitionScanner#setScopedProxyMode(ScopedProxyMode)
	 */
	ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;

    // 指定符合组件检测条件的类文件, 默认是包扫描下的"**/*.class"
	String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
    // 是否开启对标注了@Component, @Repository, @Service, @Controller注解的类进行检测。
	boolean useDefaultFilters() default true;
	// 包含的过滤条件
	Filter[] includeFilters() default {};
	// 排除的过滤条件
	Filter[] excludeFilters() default {};

	/**
	 * Specify whether scanned beans should be registered for lazy initialization.
	 * <p>Default is {@code false}; switch this to {@code true} when desired.
	 * @since 4.1
	 */
	boolean lazyInit() default false;
	/**
	 * 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
		 * &mdash; 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 {};

		/**
		 * The pattern (or patterns) to use for the filter, as an alternative
		 * to specifying a Class {@link #value}.
		 * <p>If {@link #type} is set to {@link FilterType#ASPECTJ ASPECTJ},
		 * this is an AspectJ type pattern expression. If {@link #type} is
		 * set to {@link FilterType#REGEX REGEX}, this is a regex pattern
		 * for the fully-qualified class names to match.
		 * @see #type
		 * @see #classes
		 */
		String[] pattern() default {};
	}
}

@ComponentScan扫描策略

(1)通过使用 value,basePackages 属性来指定扫描范围;
(2)自动扫描指定路径下带有 @Controller,@Service,@Repository,@Component 等注解标注的类到Spring容器中;
(3)通过 includeFilters 将扫描路径下没有以上注解的类加入 Spring 容器;
(4)通过 excludeFilters 将扫描路径下的类过滤并标识出无需加入到Spring 容器的类;
(5)通过自定义的方式,将符合规则的类加入到Spring容器中。

如何使用?

在基于SpringBoot框架的项目中,在默认的启动类上会被添加@SpringBootApplication注解,这个注解默认可以帮我们启用 SpringBoot 的自动配置功能。
@SpringBootApplication是一个组合注解,相当于使用一个@SpringBootApplication可以替代@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan几个注解联合使用。我们可以通过对@SpringBootApplication的属性scanBasePackages,实现对@ComponentScan中的属性basePackages进行自定义。

源码、示例及DEMO

源码、示例及DEMO

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cloneme01

谢谢您的支持与鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值