• springboot自动装配


    文章目录

    1、自动装配是什么及作用

    springboot的自动装配实际上就是为了从spring.factories文件中获取到对应的需要进行自动装配的类,并生成相应的Bean对象,然后将它们交给spring容器来帮我们进行管理

    2、spring自动装配的原理

    2.1、启动类上注解的作用

    @SpringBootApplication

    这个注解是springboot启动类上的一个注解,是一个组合注解,也就是由其他注解组合起来,它的主要作用就是标记说明这个类是springboot的主配置类,springboot应该运行这个类里面的main()方法来启动程序
    在这里插入图片描述
    这个注解主要由三个子注解组成:

    • @SpringBootConfiguration
    • @EnableAutoConfiguration
    • @ComponentScan
      在这里插入图片描述
    @SpringBootConfiguration

    这个注解包含了@Configuration,@Configuration里面又包含了一个@Component注解,也就是说,这个注解标注在哪个类上,就表示当前这个类是一个配置类,而配置类也是spring容器中的组件
    在这里插入图片描述
    在这里插入图片描述

    @EnableAutoConfiguration

    这个注解是开启自动配置的功能,里面包含了两个注解

    • @AutoConfigurationPackage
    • @Import(AutoConfigurationImportSelector.class)
      在这里插入图片描述
    @AutoConfigurationPackage

    这个注解的作用说白了就是将主配置类(@SpringBootApplication标注的类)所在包以及子包里面的所有组件扫描并加载到spring的容器中,这也就是为什么我们在利用springboot进行开发的时候,无论是Controller还是Service的路径都是与主配置类同级或者次级的原因
    在这里插入图片描述

    @Import(AutoConfigurationImportSelector.class)

    上一个注解我们把所有组件都加载到了容器里面,这个注解就是将需要自动装配的类以全类名的方式返回,那是怎么找到哪些是需要自动装配的类呢?

    1、AutoConfigurationImportSelector这个类里面有一个方法selectImports(),如下
    在这里插入图片描述
    2、在selectImport()方法里调用了一个getAutoConfigurationEntry()方法,这个方法里面又调用了一个getCandidateConfigurations()方法
    在这里插入图片描述
    3、在getCandidateConfigurations()方法里面调用了loadFactoryNames()方法
    在这里插入图片描述
    4、loadFactoryNames()方法里面又调用了一个loadSpringFactories()方法
    在这里插入图片描述
    5、关键就在这个loadSpringFactories()方法里面,在这个方法里,它会查找所有在META-INF路径下的spring.factories文件
    在这里插入图片描述
    在这里插入图片描述
    6、在META-INF/spring.factories这个文件里面的数据是以键=值的方式存储,然后解析这些文件,找出以EnableAutoConfiguration为键的所有值,以列表的方式返回
    在这里插入图片描述
    在这里插入图片描述

    @ComponentScan

    这个注解的作用就是扫描当前包及子包的注解

    2.2、springboot自动装配的流程

    1、在springboot启动的时候会创建一个SpringApplication对象,在对象的构造方法里面会进行一些参数的初始化工作,最主要的是判断当前应用程序的类型以及设置初始化器以及监听器,并在这个过程中会加载整个应用程序的spring.factories文件,将文件中的内容放到缓存当中,方便后续获取;

    2、SpringApplication对象创建完成之后会执行run()方法来完成整个应用程序的启动,启动的过程中有两个最主要的方法prepareContext()和refreshContext(),在这两个方法中完成了自动装配的核心功能,在run()方法里还执行了一些包括上下文对象的创建,打印banner图,异常报告期的准备等各个准备工作,方便后续进行调用;

    3、在prepareContext()中主要完成的是对上下文对象的初始化操作,包括属性的设置,比如设置环境变量。在整个过程中有一个load()方法,它主要是完成一件事,那就是将启动类作为一个beanDefinition注册到registry,方便后续在进行BeanFactoryPostProcessor调用执行的时候,可以找到对应执行的主类,来完成对@SpringBootApplication、@EnableAutoConfiguration等注解的解析工作;

    4、在refreshContext()方法中会进行整个容器的刷新过程,会调用spring中的refresh()方法,refresh()方法中有13个非常关键的方法,来完成整个应用程序的启动。而在自动装配过程中,会调用的关键的一个方法就是invokeBeanFactoryPostProcessors()方法,在这个方法中主要是对ConfigurationClassPostProcessor类的处理,这个类是BFPP(BeanFactoryPostProcessor)的子类,因为实现了BDRPP(BeanDefinitionRegistryPostProcessor)接口,在调用的时候会先调用BDRPP中的postProcessBeanDefinitionRegistry()方法,然后再调用BFPP中的postProcessBeanFactory()方法,在执行postProcessBeanDefinitionRegistry()方法的时候会解析处理各种的注解,包含@PropertySource、@ComponentScan、@Bean、@Import等注解,最主要的是对@Import注解的解析;

    5、在解析@Import注解的时候,会有一个getImport()方法,从主类开始递归解析注解,把所有包含@Import的注解都解析到,然后在processImport()方法中对import的类进行分类,例如AutoConfigurationImportSelect归属于ImportSelect的子类,在后续的过程中会调用DeferredImportSelectorHandler类里面的process方法,来完成整个EnableAutoConfiguration的加载。

    3、相关注解的作用

    @Conditional

    这个注解主要作用在类上,表示条件注入,就是当满足某个条件的时候,这个类才会被注入到 IOC 容器中,例如@ConditionalOnMissingBean,这个注解就是当容器中没有配置特定的Bean的时候,这个组件才会被注册到ioc容器中,否则会直接忽略

    自动配置中使用的条件化注解 
    ===============================================================================================================
    条件化注解 						    配置生效条件 
    ===============================================================================================================
    @ConditionalOnBean 					配置了某个特定Bean 
    @ConditionalOnMissingBean 			没有配置特定的Bean 
    @ConditionalOnClass 				Classpath里有指定的类 
    @ConditionalOnMissingClass 			Classpath里缺少指定的类 
    @ConditionalOnExpression 			给定的Spring Expression Language(SpEL)表达式计算结果为true 
    @ConditionalOnJava 					Java的版本匹配特定值或者一个范围值 
    @ConditionalOnJndi 					参数中给定的JNDI位置必须存在一个,如果没有给参数,则要有JNDI InitialContext 
    @ConditionalOnProperty 				指定的配置属性要有一个明确的值 
    @ConditionalOnResource 				Classpath里有指定的资源 
    @ConditionalOnWebApplication 		这是一个Web应用程序 
    @ConditionalOnNotWebApplication 	这不是一个Web应用程序 
    ===============================================================================================================
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    来自https://blog.csdn.net/musi_m/article/details/91893357

  • 相关阅读:
    基于XYZRGB点云实现欧式聚类分割算法C++代码
    计算机毕业设计 基于微信小程序的“共享书角”图书借还管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
    vue插件的使用方法
    C++循环队列(模板类)
    中兴助力低空经济发展,携山东移动完成5G-A通感一体商用验证
    CentOS下安装及配置MySQL
    P1562 还是N皇后
    亚马逊云服务宕机7小时,影响数万用户
    css第二课:外部样式link和import的运用及行内样式的介绍
    ping命令详解
  • 原文地址:https://blog.csdn.net/Ajekseg/article/details/126041459