【精选】spring boot的自动装配原理和注解原理

您所在的位置:网站首页 springboot自动注入省了什么步骤 【精选】spring boot的自动装配原理和注解原理

【精选】spring boot的自动装配原理和注解原理

#【精选】spring boot的自动装配原理和注解原理| 来源: 网络整理| 查看: 265

spring boot的自动装配原理 spring boot的自动装配原理自动配置原理解析源码位置启动类解析注解解析源码解析spring.factories 文件自动配置生效条件举例分析默认配置信息逻辑图展示总结

spring boot的自动装配原理 自动配置原理解析 源码位置

spring boot自动配置的源码位置在spring-boot-autoconfigure里面

在这里插入图片描述

这里可以看到这里已经有rabbitMq的一些默认配置,那么它是怎么把这些配置加载进去的呢 ,带着这个疑问,我们接着往下看。

启动类解析

首先从启动类看,作为一个springboot项目,启动类上有一个注解,必不可少,即@SpringBootApplication,最简单的一个微服务项目, 只需要加一个此注解, 便可启动。这样看来 , 自动配置原理一定和这个注解有着密不可分的联系。

按住Ctrl点击查看启动类MySpringBootApplication上的注解@SpringBootApplication

@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} ) public @interface SpringBootApplication { @AliasFor( annotation = EnableAutoConfiguration.class ) Class[] exclude() default {}; @AliasFor( annotation = EnableAutoConfiguration.class ) String[] excludeName() default {}; .................................. 注解解析

@SpringBootApplication是一个复合注解或派生注解

其中,包含以下注解 @SpringBootConfiguration:等同与@Configuration,既标注该类是Spring的一个配置类 @EnableAutoConfiguration:SpringBoot自动配置功能开启

按住Ctrl点击查看注解@EnableAutoConfiguration

package org.springframework.boot.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.context.annotation.Import; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class[] exclude() default {}; String[] excludeName() default {}; }

可以看到 , 这个注解也是一个派生注解,其中的关键功能由**@Import提供**。其导入的AutoConfigurationImportSelector , 翻译为大白话就是 自动配置导入选择器,大概表示就是这是一个自动配置,然后可以选择性导入我需要的配置文件。那么导入哪些配置文件呢?

源码解析

按住Ctrl点击查看AutoConfigurationImportSelector源码

这里注意selectImports()方法,里面有个getAutoConfigurationEntry(获取自动配置条目), 点进去有个getCandidateConfigurations(获取候选配置),进入它的代码,发现有个 SpringFactoriesLoader.loadFactoryNames(spring工厂加载-需要加载的工厂名称),进入它的代码, 发现里面loadFactoryNames方法里有个loadSpringFactories(加载spring工厂),进入他的代码,发现这么一行代码

Enumeration urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");

恍然醒悟, 原来他是要扫描META-INF文件夹下面的spring.factories文件。

总结一句话就是:

通过SpringFactoriesLoader.loadFactoryNames()扫描所有具有META-INF/spring.factories的jar包。spring-boot-autoconfigure-x.x.x.x.jar里就有一个这样的spring.factories文件。

下方是一些源码截图

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

spring.factories 文件 这个spring.factories文件也是一组一组的key=value的形式,其中一个key是EnableAutoConfiguration类的全类名,而它的value是一个xxxxAutoConfiguration的类名的列表,这些类名以逗号分隔,如下图所示:spring.factories 文件中有关自动配置的配置信息如下:

在这里插入图片描述

上面配置文件存在大量的以AutoConfiguration为结尾的类名称,这些类就是存有自动配置信息的类,而 SpringApplication在获取这些类名后再加载

这个@EnableAutoConfiguration注解通过@SpringBootApplication被间接的标记在了Spring Boot的启动类上。在SpringApplication.run(…)的内部就会执行selectImports()方法,找到所有JavaConfig自动配置类的全限定名对应的class,然后将所有自动配置类加载到Spring容器中。

随便进入一个RabbitAutoConfiguration

在这里插入图片描述

注意到有个@ConditionalOnClass,字面以为应用在类上的条件,即自动配置生效的条件

在这里插入图片描述

自动配置生效条件

以上可以不难分析出,每一个XxxxAutoConfiguration自动配置类都是在某些特定条件之下才会生效,这些条件的限制在Spring Boot中以注解的形式体现,这也是spring boot区别于之前ssm结构的显著特征。常见的条件注解有如下几项:

@ConditionalOnBean:当容器里有指定的bean的条件下。 @ConditionalOnMissingBean:当容器里不存在指定bean的条件下。 @ConditionalOnClass:当类路径下有指定类的条件下。 @ConditionalOnMissingClass:当类路径下不存在指定类的条件下。 @ConditionalOnProperty:指定的属性是否有指定的值,比如@ConditionalOnProperties(prefix=”xxx.xxx”, value=”enable”, matchIfMissing=true),代表当xxx.xxx为enable时条件的布尔值为true,如果没有设置的情况下也为true。 举例分析

我们以ServletWebServerFactoryAutoConfiguration为例来分析源码,分析一下全局配置文件中的属性是如何生效, 在这里插入图片描述 在这里插入图片描述 其中, @EnableConfigurationProperties(ServerProperties.class) 表示开始配置属性,而他后面的参数时一个ServerProperties类 ,代表加载ServerProperties服务器配置属性类,这里既是spring boot约定大于配置思想的最终实现处。

在这里插入图片描述

在这个类上,我们看到了一个非常熟悉的注解:@ConfigurationProperties,它的作用就是从配置文件中绑定属性到对应的bean上, 而@EnableConfigurationProperties负责导入这个已经绑定了属性的bean到spring容器中(见上面截图)。 那么所有其他的和这个类相关的属性都可以在全局配置文件中定义, 也就是说,真正“限制”我们可以在全局配置文件中配置哪些属性的类就是这些XxxxProperties类, 它与配置文件中定义的prefix关键字开头的一组属性是唯一对应的。

至此,我们大致可以了解。在全局配置的属性如:server.port等,通过@ConfigurationProperties注解, 绑定到对应的XxxxProperties配置实体类上封装为一个bean,然后再通过@EnableConfigurationProperties注解导入到Spring容器中。

而诸多的XxxxAutoConfiguration自动配置类,就是Spring容器的JavaConfig形式,作用就是为Spring 容器导入bean, 而所有导入的bean所需要的属性都通过xxxxProperties的bean来获得

默认配置信息

下面是端口号的一个默认配置信息 在这里插入图片描述 在这里插入图片描述

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

逻辑图展示

以上繁杂的解析和描述 , 可以参考此图理解(图片来源圣斗士Morty ) 在这里插入图片描述

总结

以上分析简短描述如下

Spring Boot启动的时候会通过@EnableAutoConfiguration注解找到META-INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,而这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个JavaConfig形式的Spring容器配置类,它能通过以Properties结尾命名的类中取得在全局配置文件中配置的属性如:server.port,而XxxxProperties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性进行绑定的。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3