springBoot @EnableAutoConfiguration深入分析
Posted H.U.C-王子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springBoot @EnableAutoConfiguration深入分析相关的知识,希望对你有一定的参考价值。
1、新建一个项目中需要提供配置类
2、在META-INF/spring.factorties在文件中配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\\
第三方jar中提供配置类全路径
实例演示:
bean-core工程:
package com.boot.config.core.domain; public class Order { }
package com.boot.config.core.domain; public class Product { }
package com.boot.config.core.config; import com.boot.config.core.domain.Order; import com.boot.config.core.domain.Product; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class BeanConfiguration { @Bean public Order createOrder() { return new Order(); } @Bean public Product createProduct() { return new Product(); } }
spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\\
com.boot.config.core.config.BeanConfiguration
config-core工程:
package com.boot.config.core; /** * 数据源的属性类 */ public class DatasourceProperties { private String driverClassName; private String url; private String username; private String password; public String getDriverClassName() { return driverClassName; } public void setDriverClassName(String driverClassName) { this.driverClassName = driverClassName; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
package com.boot.config.core; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class DataSourceConfig { @Bean @ConfigurationProperties(prefix = "jdbc") public DatasourceProperties createDatasource() { return new DatasourceProperties(); } }
spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\\
com.boot.config.core.DataSourceConfig
boot-auto工程
Pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.boot.auto.config</groupId> <artifactId>boot-auto</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>boot-auto</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!--引入三方依赖--> <dependency> <groupId>com.boot.config.core</groupId> <artifactId>bean-core</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.boot.demo</groupId> <artifactId>config-demo</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!--gson是springboot中装配的对象--> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
application.properties
jdbc.driverClassName = com.mysql.jdbc.Driver
#spring.boot.enableautoconfiguration = false 关闭配置功能,默认为true
package com.boot.auto.config.bootauto; import com.boot.config.core.DatasourceProperties; import com.boot.config.core.domain.Order; import com.boot.config.core.domain.Product; import com.google.gson.Gson; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; // 这种方式只能排除配置类 // @EnableAutoConfiguration(exclude = {BeanConfiguration.class, DataSourceConfig.class}) // @EnableAutoConfiguration(excludeName = "com.boot.config.core.config.BeanConfiguration") // @ComponentScan @SpringBootApplication // 注意点: exclude和excludeName 排除的类必须是配置类 public class BootAutoApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(BootAutoApplication.class, args); System.out.println(context.getBean(Order.class)); System.out.println(context.getBean(Product.class)); System.out.println(context.getBean(DatasourceProperties.class).getDriverClassName()); System.out.println(context.getBean("gson", Gson.class)); context.close(); } }
打印结果
可以见得,我们通过配置自动将类装配到了spring容器中
查看spring自带配置gson的配置类GsonAutoConfiguration源码如下:
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.boot.autoconfigure.gson; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import java.util.List; import java.util.function.Consumer; import java.util.function.Supplier; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @Configuration @ConditionalOnClass({Gson.class}) @EnableConfigurationProperties({GsonProperties.class}) public class GsonAutoConfiguration { public GsonAutoConfiguration() { } @Bean @ConditionalOnMissingBean public GsonBuilder gsonBuilder(List<GsonBuilderCustomizer> customizers) { GsonBuilder builder = new GsonBuilder(); customizers.forEach((c) -> { c.customize(builder); }); return builder; } @Bean @ConditionalOnMissingBean public Gson gson(GsonBuilder gsonBuilder) { return gsonBuilder.create(); } @Bean public GsonAutoConfiguration.StandardGsonBuilderCustomizer standardGsonBuilderCustomizer(GsonProperties gsonProperties) { return new GsonAutoConfiguration.StandardGsonBuilderCustomizer(gsonProperties); } private static final class StandardGsonBuilderCustomizer implements GsonBuilderCustomizer, Ordered { private final GsonProperties properties; StandardGsonBuilderCustomizer(GsonProperties properties) { this.properties = properties; } public int getOrder() { return 0; } public void customize(GsonBuilder builder) { GsonProperties properties = this.properties; PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); properties.getClass(); map.from(properties::getGenerateNonExecutableJson).toCall(builder::generateNonExecutableJson); properties.getClass(); map.from(properties::getExcludeFieldsWithoutExposeAnnotation).toCall(builder::excludeFieldsWithoutExposeAnnotation); properties.getClass(); map.from(properties::getSerializeNulls).toCall(builder::serializeNulls); properties.getClass(); map.from(properties::getEnableComplexMapKeySerialization).toCall(builder::enableComplexMapKeySerialization); properties.getClass(); map.from(properties::getDisableInnerClassSerialization).toCall(builder::disableInnerClassSerialization); properties.getClass(); map.from(properties::getLongSerializationPolicy).to(builder::setLongSerializationPolicy); properties.getClass(); map.from(properties::getFieldNamingPolicy).to(builder::setFieldNamingPolicy); properties.getClass(); map.from(properties::getPrettyPrinting).toCall(builder::setPrettyPrinting); properties.getClass(); map.from(properties::getLenient).toCall(builder::setLenient); properties.getClass(); map.from(properties::getDisablehtmlEscaping).toCall(builder::disableHtmlEscaping); properties.getClass(); map.from(properties::getDateFormat).to(builder::setDateFormat); } } }
对其中的主要两个注解进行解释:
以上是关于springBoot @EnableAutoConfiguration深入分析的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot 高级 原理分析 -- @Import注解
SpringBoot 高级 原理分析 -- @Enable*注解@Import注解
Spring构建Springboot项目 实现restful风格接口