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风格接口

SpringBoot 高级 原理分析 -- 自定义redis-starter

spring boot 约定大于配置详解

Java从入门到天黑|06高质量男性SpringBoot入门及原理(基础总结版,强烈建议收藏)