注解@ComponentScan的作用

  @Component注解及其衍生注解@RestController、@Controller、@Service和@Repository都是组件注册注解。@ComponentScan注解主要是从约定的扫描路径中,识别标注了组件注册注解的类,并且把这些类自动注册到spring IoC容器中,这些类就是我们通常所言的bean。IoC容器是Spring的特色之一,可以使用它管理bean。当然,@Configration注解修饰的类也会被托管给IoC容器。

  举个例子,你在微博上@某某,对方会优先看到这条信息,并给你反馈。同理,在Spring中,你标识一个@符号,那么Spring就会关照一下,从你这里拿到一个Bean(自动注册)或者给出一个Bean(自动装配)。

  思考:Spring怎么知道哪些Java类应该当作bean 注册到IoC容器中?

  解析:使用配置文件或者注解的方式进行标识需要处理的java类,这些被标注的类被Spring识别为bean类。

组件扫描路径

  注解@ComponentScan 如果不设置value属性,默认扫描路径是启动类 XxxApplication.java 所在目录及其子目录,所以最好还是配置value属性,减少加载时间,提高系统启动速度。

  比如启动类在包 com.eg.wiener 下面,那么项目启动时,会默认扫描wiener包及其子包下的所有类。也就是说,即便不明确标注@ComponentScan,Spring Boot也会自动搜索当前应用主入口目录及其下方子目录。如果其它包中的bean 不在当前主包路径下面,则应使用@ComponentScan设置value属性,配置扫描路径。如果定义了错误的扫描路径,那么在使用注解@Autowired自动装配Bean时会出错,报a bean of type that could not be found错误。

配置扫描路径

  @ComponentScan注解既可以扫描包,也可以扫描指定的类。我们只需要指定一个需要扫描的路径,就可以达到更改扫描路径的目的。

  1. 包路径

  通过value属性设置需要扫描的包:

@ComponentScan({"com.company.user","com.company.service"})

  1. 类路径

  通过basePackageClasses属性指定需要扫描的类:

@ComponentScan(basePackageClasses={XxxService.class, YyyService.class})

@Component和@ComponentScan的区别

  @Component和@ComponentScan有什么区别?二者用于不同目的,咱们结合学生抢答老师的问题这一场景来解释。@Component表示哪些类可能是bean的候选者,就像哪些同学举手抢答问题一样。@ComponentScan 搜索组件包中的类,找到所有bean的候选者,就像老师试图找出哪些同学举手抢答问题。通俗一点解释,就是全班同学代表扫描路径下的所有类,抢答者就是被@Component注解修饰的类,而找到所有抢答者的老师就是@ComponentScan。延伸一点,成功抢到答题机会的同学就是被@Autowire装配的bean了。

注解@ComponentScan实现原理

  本节介绍 Spring Boot 中注解 @ComponentScan 的实现原理。

  下面介绍一下ComponentScan注解中几个常用的属性。

  1. String[] value() default {};

    指定包扫描路径,value属性的值,就是项目中的一个具体路径。value属性的类型是String数组,也就是支持一次指定多个包扫描路径。这个属性上面添加了一个注解,@AliasFor("basePackages"),这个注解的意思就是说,value这个属性等价于basePackages属性。关于basePackages属性,下面会讲到。
  2. Class<?>[] basePackagesClasses() default {};

    扫描具体的类。basePackagesClasses属性的类型是Class数组,也就是说支持同时指定多个扫描类。
  3. Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator. class;

    配置beanName生成器,默认是BeanNameGenerator。一般情况下,我们都是使用默认的beanName生成器,但是Spring实现了beanName生成器的可配置。
  4. boolean useDefaultFilters() default true;

    是否对含有以下注解的类开启检测,默认是开启的。

    @Component

    @Repository

    @Service

    @Controller
  5. ComponentScan.Filter[] includeFilters() default {};

    指定某些Filter扫描到的类。听起来有些费劲,说白了就是指定了类型,扫描指定的这些类型。可选类型有5种,定义在枚举类FilterType中:

    第一种:ANNOTATION

    第二种:ASSIGNABLE_TYPE

    第三种:ASPECTJ

    第四种:REGEX,正则表达式。

    第五种:CUSTOM,自定义类型。
  6. ComponentScan.Filter[] excludeFilters() default {};

    排除过滤器扫描的的类。

Reference

Spring Boot注解之@ComponentScan用法和实现原理的更多相关文章

  1. Spring boot注解(annotation)含义详解

    Spring boot注解(annotation)含义详解 @Service用于标注业务层组件@Controller用于标注控制层组件(如struts中的action)@Repository用于标注数 ...

  2. 73. Spring Boot注解(annotation)列表【从零开始学Spring Boot】

    [从零开始学习Spirng Boot-常见异常汇总] 针对于Spring Boot提供的注解,如果没有好好研究一下的话,那么想应用自如Spring Boot的话,还是有点困难的,所以我们这小节,说说S ...

  3. Spring Boot注解大全,一键收藏了!

    本文首发于微信公众号[猿灯塔],转载引用请说明出处 今天是猿灯塔“365天原创计划”第5天. 今天呢!灯塔君跟大家讲: Spring Boot注解大全 一.注解(annotations)列表 @Spr ...

  4. Spring boot 注解简单备忘

    Spring boot 注解简单备忘 1.定义注解 package com.space.aspect.anno;import java.lang.annotation.*; /** * 定义系统日志注 ...

  5. Spring Boot 注解之ObjectProvider源码追踪

    最近依旧在学习阅读Spring Boot的源代码,在此过程中涉及到很多在日常项目中比较少见的功能特性,对此深入研究一下,也挺有意思,这也是阅读源码的魅力之一.这里写成文章,分享给大家. 自动配置中的O ...

  6. Spring Boot 注解详解

    一.注解(annotations)列表 @SpringBootApplication:包含了@ComponentScan.@Configuration和@EnableAutoConfiguration ...

  7. Java 小记 — Spring Boot 注解

    前言 本篇随笔将对 Spring Boot 中的常用注解做一个简单的整理归档,写作顺序将从启动类开始并逐步向内外扩展,目的即为了分享也为了方便自己日后的回顾与查阅. 1. Application 启动 ...

  8. Spring boot注解使用

    1:@SpringBootApplication 注解 a:scanBasePackages 与scanBasePackageClasses配置Spring启动时扫描的包路径或者扫描的字节码文件 b: ...

  9. Spring Boot注解(annotation)列表

    (1)@SpringBootApplication 申明让spring boot自动给程序进行必要的配置,这个配置等同于: @Configuration ,@EnableAutoConfigurati ...

  10. spring mvc注解和spring boot注解

    1 spring mvc和spring boot之间的关系 spring boot包含spring mvc.所以,spring mvc的注解在spring boot总都是可以用的吗? spring b ...

随机推荐

  1. GUI图形界面编程(Java)

    GUI编程 组件 窗口 弹窗 面板 文本框 列表框 按钮 图片 监听事件 鼠标 键盘事件 破解工具 1.简介 Gui的核心技术:Swing.AWT 2.AWT 2.1.AWT介绍 1.包含了很多类和接 ...

  2. java真是一门丑陋的语言,我都new Thread.run了然后你告诉我是在当前线程中运行

    new Thread(x->{}).run(); 上方代码怎么看都应该是要开启新线程的,毕竟都已经new了.但是上方代码居然是在当前线程中运行!想要开启新线程得用.start()方法,如下: n ...

  3. Suspense和vue-async-manager

    Suspense Suspense是 Vue3.x 中新增的特性, 那它有什么用呢?别急,我们通过 Vue2.x 中的一些场景来认识它的作用. Vue2.x 中应该经常遇到这样的场景: <tem ...

  4. Go语言修改字符串

    Go 语言的字符串无法直接修改每一个字符元素,只能通过重新构造新的字符串并赋值给原来的字符串变量实现.请参考下面的代码: angel := "Heros never die" an ...

  5. mysql查询指定表所有的字段信息 columns

    show columns from 表名: desc 表名;(全写:describe 表名) show create table 表名;

  6. MFC使用WM_COPYDATA消息进行进程间的通讯

    一.介绍 Windows上MFC应用程序可使用WM_COPYDATA可以完成两个进程之间的通讯.当一个应用向另一个应用传送数据时,发送方需调用SendMessage函数,参数是目的窗口的句柄.传递数据 ...

  7. PKI(Public Key Infrastructure,公钥基础设施)常见标准介绍

    ASN.1 - 数据结构描述语言 文件编码格式 DER编码格式 PEM编码格式 证书.密码学Key格式标准 X.509标准 PKCS(公钥加密标准)系列(PKCS#1.PKCS#8.PKCS#12) ...

  8. AOP流程及原理

    目录 一.AOP结构介绍 @Pointcut 通知 原理 连接点 拦截器 二.Bean介入点 EnableAspectJAutoProxy AspectJAutoProxyRegistrar Anno ...

  9. eolinker响应预处理:传参解决方法(响应数据截取后设置为变量)

    特别注意:需要使用全局变量或者预处理前务必阅读本链接https://www.cnblogs.com/becks/p/13713278.html 一.案例1 1.场景描述: 后一个请求需要前一个请求提供 ...

  10. 使用CAMEL创建第一个Agent Society

    CAMEL介绍 CAMEL 是一个开源社区,致力于探索代理的扩展规律.相信,在大规模研究这些代理可以提供对其行为.能力和潜在风险的宝贵见解.为了促进这一领域的研究,实现了并支持各种类型的代理.任务.提 ...