• springboot的自动配置


    Spring Boot理念是约定优于配置,它通过实现了自动配置(大多数用户平时习惯设置的配置作为默认配置)的功能来为用户快速构建出标准化的应用。Spring Boot的特点可以概述为如下几点:

    • 内置了嵌入式的Tomcat、Jetty等Servlet容器,应用可以不用打包成War格式,而是可以直接以Jar格式运行。

    • 提供了多个可选择的”starter”以简化Maven的依赖管理(也支持Gradle),让您可以按需加载需要的功能模块。

    • 尽可能地进行自动配置,减少了用户需要动手写的各种冗余配置项,Spring Boot提倡无XML配置文件的理念,使用Spring Boot生成的应用完全不会生成任何配置代码与XML配置文件。

    • 提供了一整套的对应用状态的监控与管理的功能模块(通过引入spring-boot-starter-actuator),包括应用的线程信息、内存信息、应用是否处于健康状态等,为了满足更多的资源监控需求,Spring Cloud中的很多模块还对其进行了扩展。

    Spring Boot的自动配置看起来神奇,其实原理非常简单,背后全依赖于@Conditional注解来实现的。

    什么是@Conditional?

    @Conditional是由Spring 4提供的一个新特性,用于根据特定条件来控制Bean的创建行为。而在我们开发基于Spring的应用的时候,难免会需要根据条件来注册Bean。

    在业务复杂的情况下,显然需要使用到@Conditional注解来提供更加灵活的条件判断,例如以下几个判断条件:

    • 在类路径中是否存在这样的一个类。

    • 在Spring容器中是否已经注册了某种类型的Bean(如未注册,我们可以让其自动注册到容器中,上一条同理)。

    • 一个文件是否在特定的位置上。

    • 一个特定的系统属性是否存在。

    • 在Spring的配置文件中是否设置了某个特定的值。

    我们已经在搭建springboot工程的时候体会到了配置的简洁性,没有了之前使用spring所需配置的繁琐。

    那么springboot是如何做到的呢?

    我们在启动类中都要添加@SpringBootApplication,有了这个注解马上就能够让整个应用跑起来。

    实际上它只是一个组合注解,包含@Configuration、@EnableAutoConfiguration、@ComponentScan这三个注解。

    从启动类的@SpringBootApplication进入在里面找到了@EnableAutoConfiguration,

    1.png

    2.png

    @EnableAutoConfiguration里通过@Import导入了EnableAutoConfigurationImportSelector,

    3.png

    进入他的父类AutoConfigurationImportSelector

    4.png

    找到selectImports()方法,他调用了getCandidateConfigurations()方法,在这里,这个方法又调用了Spring Core包中的loadFactoryNames()方法。这个方法的作用是,会查询META-INF/spring.factories文件中包含的JAR文件。

    5.png

    当找到spring.factories文件后,SpringFactoriesLoader将查询配置文件命名的属性。

    6.png

    7.png

    Jar文件在org.springframework.boot.autoconfigure的spring.factories

    8.png

    spring.factories内容如下(截取部分),在这个文件中,可以看到一系列Spring Boot自动配置的列表。
    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,
    org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,
    org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,
    org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,
    org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,
    org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,
    org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,
    org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,
    org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,
    org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,
    org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,
    org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,
    org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,
    org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,
    org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,

    下面我们来分析一下spring boot autoconfigure里面的MongoAutoConfiguration(mongodb的自动配置),相信你就会明白这套自动配置机制到底是怎么一回事儿:

    @Configuration
    @ConditionalOnClass({MongoClient.class})  
    @EnableConfigurationProperties({MongoProperties.class}) //开启属性注入。
    @ConditionalOnMissingBean(
        type = {"org.springframework.data.mongodb.MongoDbFactory"}
    ) 
    public class MongoAutoConfiguration {
        @Autowired
        private MongoProperties properties;
        @Autowired(
            required = false
        )
        private MongoClientOptions options;
        @Autowired
        private Environment environment;
        private MongoClient mongo;
        public MongoAutoConfiguration() {
        }
        @PreDestroy
        public void close() {
            if(this.mongo != null) {
                this.mongo.close();
            }
        }
        @Bean //使用java配置,当容器中没有这个bean的时候执行初始化
        @ConditionalOnMissingBean
        public MongoClient mongo() throws UnknownHostException {
            this.mongo = this.properties.createMongoClient(this.options, this.environment);
            return this.mongo;
        }
    }

    首先这被@Configuration注解了,是一个配置类,当满足以下条件这个bean被装配:

    • 当MongoClient在类路径下。

    • 当容器中没有org.springframework.data.mongodb.MongoDbFactory这类bean的时候。

    此外,我们可以看一下通过@EnableConfigurationProperties({MongoProperties.class}) 自动注入的属性

    @ConfigurationProperties(
        prefix = "spring.data.mongodb"
    )
    public class MongoProperties {
        public static final int DEFAULT_PORT = 27017;
        private String host;
        private Integer port = null;
        private String uri = "mongodb://localhost/test";
        private String database;
        private String authenticationDatabase;
        private String gridFsDatabase;
        private String username;
        private char[] password;
        private Class<?> fieldNamingStrategy;
    
        ......
    }

    所以在我们什么都不干的情况下,只需要引入spring-data-mongodb这个依赖再加上默认的MongoDB server我们就能够快速集成MongoDB,用MongodbTemplate访问数据库。

    同时我们可以通过在application.yaml中修改spring.data.mongodb相关的参数就能够修改连接配置,如:

    spring:
        data:
            mongodb:
                host: localhost
                port: 27017
                username: chingzhu
                password: test123
                database: icekredit

    参考:Spring Boot 自动配置的 “魔法” 是如何实现的?

  • 相关阅读:
    SDUT-2131_数据结构实验之栈与队列一:进制转换
    HDU-6290_奢侈的旅行(Dijstra+堆优化)
    SDUT-2054_数据结构实验之链表九:双向链表
    SDUT-3331_数据结构实验之链表八:Farey序列
    Ubuntu安装redis
    magento2站点迁移
    JS 代码中到底加不加分号
    magento2常见的命令
    ngx_pagespeed-nginx前端优化模块介绍
    搜索引擎网站收录地址大全
  • 原文地址:https://www.cnblogs.com/xiangkejin/p/9060677.html
Copyright © 2020-2023  润新知