spring boot 自动配置原理

1).spring boot启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration

2).通过@EnableAutoConfiguration中AutoConfigurationImportSelector给容器中导入了一系列的组件通过List<String> configurations = getCandidateConfigurations(annotationMetadata,attributes);获取候选的配置,下一步通过SpringFactoriesLoader.loadFactoryNames() 扫描所有 jar 包类路径下的META-INF/spring.factories,将扫描到的文件内容包装成properties对象,从properties中获取到EnableAutoConfiguration.class类名对应的值,然后把他们添加到容器中。

将类路径下  META-INF/spring.factories 里面配置的 所有EnableAutoConfiguration的值添加到容器中

一下就是该文件中的一部分代码:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,等等一些列的类

每一个这样的 XXXXAutoConfiguration类都是容器中的一个组件,都加入到容器中,用他们来自动配置

3).每个自动配置类@EnableAutoConfiguration进行自动配置功能

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

	/**
	 * Exclude specific auto-configuration classes such that they will never be applied.
	 * @return the classes to exclude
	 */
	Class<?>[] exclude() default {};

	/**
	 * Exclude specific auto-configuration class names such that they will never be
	 * applied.
	 * @return the class names to exclude
	 * @since 1.3.0
	 */
	String[] excludeName() default {};

}

@AutoConfigurationPackage:自动配置包

  @Import(AutoConfigurationPackages.Registrar.class)

  spring的底层注解@Import,给容器导入一个组件()

  AutoConfigurationPackages.Registrar.class:是将@SpringBootConfiguration 标注的类所在的包下的子包里面所有的组建扫描到spring容器中。

  @Import(AutoConfigurationImportSelector.class):导入组件;

 将所有需要导入的组件以全类名的方式返回:这些组件就会被添加到容器中

	@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
				.loadMetadata(this.beanClassLoader);
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		List<String> configurations = getCandidateConfigurations(annotationMetadata,
				attributes);
		configurations = removeDuplicates(configurations);
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		checkExcludedClasses(configurations, exclusions);
		configurations.removeAll(exclusions);
		configurations = filter(configurations, autoConfigurationMetadata);
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return StringUtils.toStringArray(configurations);
	}

configurations:里面存储的数组信息就是需要spring自动配置的全类名。(XXX.AutoConfiguration)。 

4).以HttpEncodingAutoConfiguration为例解释自动配置原理

@Configuration // 这是一个配置类 也可以给容器中添加组件
// 启用指定类的ConfigurationProperties功能
// 将配置文件中对应的值跟HttpEncodingProperties绑定,并将HttpEncodingProperties加入IOC容器中
@EnableConfigurationProperties(HttpEncodingProperties.class)
// spring底层@Conditional注解,根据不同的条件。如果满足指定条件,整个配置类才生效
// 判断当前应用是否web应用
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
// 判断当前项目有没有这个类CharacterEncodingFilter:MVC中乱码解决的过滤器
@ConditionalOnClass(CharacterEncodingFilter.class)
// 判断配置文件中是否存在某个配置spring.http.encoding.enabled,如果不存在也是成立的
// 也会通过 matchIfMissing = true判断默认生效
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {

	private final HttpEncodingProperties properties;

	public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
		this.properties = properties;
	}

	@Bean
	@ConditionalOnMissingBean
	public CharacterEncodingFilter characterEncodingFilter() {
		CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
		filter.setEncoding(this.properties.getCharset().name());
		filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
		filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
		return filter;
}

根据当前不同的条件判断,决定当前配置类是否生效?

一旦配置类生效:这个配置类就会给容器中添加各种组件,组件的属性来源于对应的XXXProperties类中获取的,这些类的每一个属性都来源于配置文件。

5).所有配置文件中能配置的属性在 xxxProperties类中封装着,配置文件中能配什么,这里就有什        么,

//从配置文件中获取指定的值和bean的属性进行绑定@ConfigurationProperties(prefix = "spring.http.encoding")
public class HttpEncodingProperties {  。。。}

1.spring boot启动会加载大量的自动配置类

2.我们看我们需要的功能spring boot 默认写好的自动配置类有没有Properties

3.我们看这个自动配置类中配置了那些组件,没有的话自己编写

4.给容器中自动配置类添加组件时候,会从prperties类中获取某些属性,我们就可以在配置文件中指定他的值

XXXAutoConfiguration自动配置类给容器中添加组件就会有对应的XXXProperties来封装配置文件中相关的属性

原文地址:https://www.cnblogs.com/wuzhenzhao/p/9151673.html

时间: 2024-10-13 22:51:14

spring boot 自动配置原理的相关文章

Spring Boot自动配置原理(转)

第3章 Spring Boot自动配置原理 3.1 SpringBoot的核心组件模块 首先,我们来简单统计一下SpringBoot核心工程的源码java文件数量: 我们cd到spring-boot-autoconfigure工程根目录下.执行 $ tree | grep -c .java$ 模块 java文件数 spring-boot 551 spring-boot-actuator 423 spring-boot-autoconfigure 783 spring-boot-devtools

4、Spring Boot 自动配置原理

1.4 Spring Boot 自动配置原理 简介 spring boot自动配置功能可以根据不同情况来决定spring配置应该用哪个,不应该用哪个,举个例子: Spring的JdbcTemplate是不是在Classpath里面?如果是,并且DataSource也存在,就自动配置一个JdbcTemplate的Bean Thymeleaf是不是在Classpath里面?如果是,则自动配置Thymeleaf的模板解析器.视图解析器.模板引擎 那个这个是怎么实现的呢?原因就在于它利用了Spring的

浅析spring boot自动配置原理

spring boot 源码刨析: 1.spring boot 启动类 @SpringBootApplication public class MgmtApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(MgmtAppli

Spring Boot自动配置原理分析

 [email protected]注解 @Configuratin注解是Spring框架提供的,表示当前类是一个配置类. @SpringBootConfiguration注解和 @Configuratin注解都是标识一个可以被组件扫描器扫描的配置类, 只不过@SpringBootConfiguration是被Spring Boot进行了重新的命名和封装. [email protected]注解 @EnableAutoConfiguration注解是一个组合注解,由@AutoConfigurat

Springboot 系列(三)Spring Boot 自动配置

注意:本 Spring Boot 系列文章基于 Spring Boot 版本 v2.1.1.RELEASE 进行学习分析,版本不同可能会有细微差别. 前言 关于配置文件可以配置的内容,在 Spring Boot 官方网站已经提供了完整了配置示例和解释. 可以这么说,Spring Boot 的一大精髓就是自动配置,为开发省去了大量的配置时间,可以更快的融入业务逻辑的开发,那么自动配置是怎么实现的呢? 1. @SpringBootApplication 跟着 Spring Boot 的启动类的注解

Spring Boot 自动配置之@Conditional的使用

Spring Boot自动配置的"魔法"是如何实现的? 转自-https://sylvanassun.github.io/2018/01/08/2018-01-08-spring_boot_auto_configure/ Spring Boot是Spring旗下众多的子项目之一,其理念是约定优于配置,它通过实现了自动配置(大多数用户平时习惯设置的配置作为默认配置)的功能来为用户快速构建出标准化的应用.Spring Boot的特点可以概述为如下几点: 内置了嵌入式的Tomcat.Jett

spring boot自动配置实现

自从用了spring boot,都忘记spring mvc中的xml配置是个什么东西了,再也回不去.为啥spring boot这么好用呢, 约定大于配置的设计初衷, 让我们只知道维护好application.properties(或application.yml)文件就可以了,我们在配置文件里可以设置数据源参数,可以设置服务端口,可以设置redis的地址等等.我们经常会看一些包含starter名字的jar包,如spring-boot-starter-data-redis,引入这些jar包,我们就

Spring Boot自动配置类

http://docs.spring.io/spring-boot/docs/current/api/overview-summary.html http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#auto-configuration-classes 前提 1.一般来说,xxxAware接口,都提供了一个setXxx的方法,以便于其实现类将Xxx注入自身的xxx字段中,从而进行操作. 例如 Applicatio

Spring Boot自动配置实例

spring boot之所以能够自动配置bean,是通过基于条件来配置Bean的能力实现的. 常用的条件注解如下 @ConditionalOnBean:当容器里存在指定的Bean的条件下 @ConditionalOnClass:当前类路径下存在指定的类的条件下 @ConditionalOnExpression:基于SpEL表达式作为判断条件 @ConditionalOnJava:基于JVM版本作为判断条件 @ConditionalOnJndi:在JNDI存在的条件下查找指定的位置 @Condit