Spring boot自动配置原理-阿里云开发者社区

开发者社区> 武汉-李凯> 正文

Spring boot自动配置原理

简介: Spring boot自动配置原理
+关注继续查看

Spring boot自动配置原理

自动配置,顾名思义就是不需要开发者自己去配置应用程序,而是只要满足springboot实现自动配置的条件即可。具体来说就是Springboot根据开发者添加的jar包依赖项来自动配置springboot程序的。

1.环境

spring-boot 1.5.9.RELEASE

2.配置类注册到IOC容器的流程图

流程图.png

3.从代码开始分析

3.1、启动类
@SpringBootApplication
public class SpringbootLearnApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootLearnApplication.class, args);
    }
}
3.2、@SpringBootApplication注解
//省略部分注解
@SpringBootConfiguration//表示这是SpringBoot的配置类
@EnableAutoConfiguration//这个注解的作用就是让SpringBoot开启自动配置
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)//开启组件扫描
public @interface SpringBootApplication

@SpringBootApplication是一个组合注解,其中@EnableAutoConfiguration开启了自动配置功能。

3.3、@EnableAutoConfiguration注解
//省略部分注解
@AutoConfigurationPackage//添加该注解的类所在的package作为自动配置package进行管理
@Import({EnableAutoConfigurationImportSelector.class})//利用EnableAutoConfigurationImportSelector给容器中导入一些组件
public @interface EnableAutoConfiguration

EnableAutoConfigurationImportSelector类继承AutoConfigurationImportSelector类,查看AutoConfigurationImportSelector类源代码

 public String[] selectImports(AnnotationMetadata annotationMetadata) {
         .... 
        //获取候选的配置
         List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
         ....       
    }

getCandidateConfigurations方法

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
        ....
    }
3.4、SpringFactoriesLoader类的loadFactoryNames方法

SpringFactoriesLoader类的loadFactoryNames方法,扫描所有jar包类路径下 META-INF/spring.factories 把扫描到的这些文件的内容包装成properties对象 从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中

public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
        String factoryClassName = factoryClass.getName();

        try {
            Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
            ArrayList result = new ArrayList();
            while(urls.hasMoreElements()) {
                URL url = (URL)urls.nextElement();
                Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
                String factoryClassNames = properties.getProperty(factoryClassName);      result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
            }
            return result;
        } catch (IOException var8) {
            throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() + "] factories from location [" + "META-INF/spring.factories" + "]", var8);
        }
    }
3.5、spring.factories在spring-test-autoconfigure下的示例
# AutoConfigureCache auto-configuration imports
org.springframework.boot.test.autoconfigure.core.AutoConfigureCache=\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration

# AutoConfigureDataJpa auto-configuration imports
org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa=\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration
    .......

4.HttpEncodingAutoConfiguration自动配置过程

4.1、HttpEncodingAutoConfiguration
@Configuration //配置类,可以给容器中添加组件
@EnableConfigurationProperties({HttpEncodingProperties.class})//启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到ioc容器中
@ConditionalOnWebApplication//当Spring服务为web时,才使注解的类生效
@ConditionalOnClass({CharacterEncodingFilter.class})//判断当前项目有没有这个类
@ConditionalOnProperty(
    prefix = "spring.http.encoding",
    value = {"enabled"},
    matchIfMissing = true
)//判断配置文件中是否存在某个配置spring.http.encoding.enabled;如果不存在,判断也是成立的,即使在配置文件中不配置spring.http.encoding.enabled=true,配置也是生效的
public class HttpEncodingAutoConfiguration {
    
    //HttpEncoding的配置类,其中字段已经和配置文件映射了
    private final HttpEncodingProperties properties;

    //当前构造函数参数的值,会从容器中获取
    public HttpEncodingAutoConfiguration(HttpEncodingProperties properties)     {
        this.properties = properties;
    }

    @Bean//给容器中添加一个组件CharacterEncodingFilter
    @ConditionalOnMissingBean({CharacterEncodingFilter.class})//判断容器有没有这个组件
    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;
    }

HttpEncodingAutoConfiguration会根据当前不同的条件判断,决定这个配置类是否生效,如果这个配置类生效,会给容器中添加各种组件;这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;

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

    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    private Charset charset = DEFAULT_CHARSET;

    private Boolean force;

    private Boolean forceRequest;

    private Boolean forceResponse;

    private Map<Locale, Charset> mapping;

    public Charset getCharset() {
        return this.charset;
    }
    .....
}
4.3、总结
  • SpringBoot启动会加载大量的自动配置类;给容器中自动配置添加组件的时候,会从propeties类中获取配置文件中指定这些属性的值
  • xxxxAutoConfigurartion:⾃动配置类给容器中添加组件;
  • xxxxProperties:封装配置文件中相关属性;
小技巧:
在配置文件中配置:debug=true,可以在控制台打印自动配置报告。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java的内存模型
java的后端服务器开发中"高效并发"是我们经常会碰到的,而要写出高效的代码需要更多的积累与实践。而一些基础的内容是往这个方向发展的基石。所以我们就来介绍下
4 0
【2020 Java基础快速学习路线】写了很久,这是一份最适合普通大众、非科班的路线
【2020 Java基础快速学习路线】写了很久,这是一份最适合普通大众、非科班的路线
3 0
教妹学Java(八):初识Java变量
教妹学Java(八):初识Java变量
3 0
云迁移SaaS如何入驻阿里云工具应用市场
HyperMotion SaaS是一款基于云原生理念开发的云迁移和云灾备的SaaS平台,2020年7月,HyperMotion迁移版本正式入驻阿里云工具应用市场。用户登陆阿里云后,可以直接以SaaS模式使用产品,而无须再到云市场启动实例的方式。由于与阿里云的用户体系、RAM系统、支付系统彻底打通,用户在使用感受上更加便捷。
5 0
雇佣劳工冒充AI?校园外卖机器人竟是远程人工操纵,时薪2美元
活跃在美国著名学府加州大学伯克利分校(UC Berkeley)校园的「明星」外卖机器人 Kiwibot,尽管看起来像是自动驾驶,实际上却是雇佣了远在哥伦比亚的真人进行远程人工操纵。最近,创业公司 Kiwibot 也陷入了用真人冒充 AI 的舆论漩涡。
3 0
想学习,无方法,十年老码农告诉你方法
想学习,无方法,十年老码农告诉你方法
4 0
volatile关键字
volatile关键字是我们经常在面试过程中碰到的一个问题,本文来介绍下这个关键字 原则性,可见性,有序性
6 0
别翻了,Lambda 表达式入门,看这篇就够了(1)
别翻了,Lambda 表达式入门,看这篇就够了
3 0
JVM中的类加载器
把类加载阶段中的"通过一个类的全限定名来获取描述此类的二进制字节流"这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类,实现这个动作的代码模块称为类加载器。
3 0
教妹学Java(七):究竟什么是JVM?
教妹学Java(七):究竟什么是JVM?
3 0
2
文章
0
问答
来源圈子
更多
阿里云GTS能力中心(浩鲸智能),从交付的视角探讨数字化转型过程中大型软件开发实践、以及阿里云产品在各行业被集成的案例分享、技术沉淀等内容。敬请关注!
+ 订阅
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载