Springboot - 包扫描原理解析

Spring中的包扫描

在Spring中bean的注入有两种方式:

  • 自定义bean:xml或配置类
  • 注解,设置自动扫描

Spring中xml配置文件:
在这里插入图片描述

**配置类:**在类上加注解@Configuration,将类设置为配置类代替xml配置文件
在这里插入图片描述

由程序员手动设置bean是比较繁琐的,Spring又提供了偷懒的方法

注解、自动扫描:

在springmvc.xml中<context:component-scan base-package="com.learn.controller"/>,即可扫描controller包下的所有bean

在这里插入图片描述

@Controller注解即表示该类为Spring中的一个bean

在这里插入图片描述

配置类中的自动扫描:即然@Configuration注解的配置类类似与xml配置文件,那能不能设置自动扫描?

@ComponentScan 注解:默认扫描该类所在的包下所有的配置类

在这里插入图片描述

那么没有在Config类中注入的bean,只要在当前目录下设置了,就可以从Spring容器中得到:

例如:当前目录下Beer并没有在Config中注入

在这里插入图片描述

Beer类设置为Spring组件:
在这里插入图片描述

测试类依旧可以直接得到:

在这里插入图片描述

Spring中通过@ComponentScan注解或者 < context:component-scan >标签完成包扫描

那么SpringBoot中呢?


SpringBoot中的包扫描

我们知道SpringBoot中:我们编写的类比较放置在xxApplication类所在目录下

这不就是前面Spring中的包扫描:扫描该类所在的包下所有的配置类

一个SpringBoot案例:

在这里插入图片描述

在这里插入图片描述

我们找不到任何关于包扫描的xml或者注解,定义好一个controller,然后启动就可以访问了?这是为什么?

这就是为什么说SpringBoot是Spring的精简加强版


SpringBoot包扫描原理

一切的秘密都在这:

在这里插入图片描述

SpringBoot的启动类中有很多东西,这里仅分析包扫描的原理

@SpringBootApplication

@SpringBootApplication注解的三个重要子注解:

在这里插入图片描述

  • @SpringBootConfiguration注解就是SpringBoot版的@Configuration注解:表示这是一个配置类
  • @EnableAutoConfiguration注解是设置启动时的自动装配
  • @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })即包扫描

里面的内容是什么意思呢?excludeFilters表示哪些类不用被扫描到

在这里插入图片描述

  • @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class)

custom表示自定义过滤规则(需要实现TypeFilter接口),TypeExcludeFilter就是SpringBoot定义的过滤类

  • @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)

自定义的匹配注册的自动配置类的过滤类AutoConfigurationExcludeFilter

那么是如何实现扫描该类所在的包呢?

SpringApplication.run(MyspringbootApplication.class, args)

该方法是SpringBoot的核心,其中有很多方法用于准备SpringBoot的环境、配置等

我们关注3个有关context方法:

  • createApplicationContext()

  • prepareContext(…)

  • refreshContext(context)

createApplicationContext: 创建Spring容器,返回ConfigurableApplicationContext
我们都知道ApplicationContext就是Spring的核心的IoC容器

在这里插入图片描述

prepareContext: 即准备context

其中有一个load(context, sources.toArray(new Object[0]))方法(多层方法),最终进入

在这里插入图片描述

在这里插入图片描述

isComponent方法判断类是否有Component的注解,明显启动类是有的,即将启动类注册

refreshContext(context):刷新context

很复杂
refreshContext方法 -》 invokeBeanFactoryPostProcessors方法 -》ConfigurationClassPostProcessor类 -》 processConfigBeanDefinitions方法 -》 parser.parse(candidates)方法 -》parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());方法 -》 processConfigurationClass方法 -》doProcessConfigurationClass方法

终于到了处理ComponentScan注解的方法:

在这里插入图片描述

其中的componentScans.isEmpty()的判断,即判定配置@ComponentScan的这个属性,得到添加的这个启动类的名字的最后一个点之前的路径,比如启动类是A.B.C.D.class, 那么路径就是A.B.C.D

Spring会通过传入的路径来遍历下面的每一个class


结语

SpringBoot是Spring的简化,需要配置的操作全部实现了自动化(自动装配)

SpringBoot的包扫描是隐藏的,需要深究才能找到

SpringBoot源码太复杂了,希望以后能看懂

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot的自动装配原理可以分为以下几个关键步骤: 1. 启动过程:在Spring Boot应用启动时,会执行SpringApplication类的run方法。该方法会创建Spring应用上下文,并触发自动装配过程。 2. 自动装配过程:自动装配过程主要依赖于条件注解和自动配置类。 - 条件注解:Spring Boot提供了一系列条件注解,如@ConditionalOnClass、@ConditionalOnBean、@ConditionalOnProperty等。这些注解可以根据特定的条件来决定是否进行自动配置。 - 自动配置类:自动配置类使用@Configuration注解进行标识,通过@Bean注解来声明需要自动配置的Bean。自动配置类通常使用@Conditional注解来指定条件,只有当满足条件时才会生效。 3. 自动配置类的加载:Spring Boot会自动扫描项目中的META-INF/spring.factories文件,该文件中定义了需要自动配置的类。Spring Boot会根据这些类的条件进行加载和实例化。 4. Bean的创建:在自动配置类中使用@Bean注解声明的Bean会被Spring容器自动创建和管理。这些Bean的创建过程会经过Spring的各个处理器,如BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor等。 下面是一个简单的示例来说明Spring Boot自动装配的原理: ```java @Configuration @ConditionalOnClass(MyService.class) public class MyAutoConfiguration { @Bean public MyService myService() { return new MyService(); } } ``` 在上述示例中,@ConditionalOnClass注解表示只有当MyService类在类路径中存在时,该自动配置类才会生效。当应用启动时,Spring Boot扫描到该自动配置类,并根据条件判断是否需要进行自动配置。如果满足条件,Spring Boot会实例化并管理MyService的Bean。 通过自动装配,Spring Boot可以根据项目的实际需求,自动配置和管理各种Bean,从而减少了开发人员的配置工作,提高了开发效率。 请注意,上述示例只是简单示意,并不涵盖所有细节。实际的自动装配过程还涉及到条件判断、依赖关系处理、配置属性绑定等复杂的逻辑。如果你想深入了解Spring Boot的自动装配原理,建议阅读Spring Boot的源码以及相关文档。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值