SpringBoot框架:Profile,配置文件加载位置,外部配置加载顺序,自动配置原理

Profile

Profile是Spring对不同环境提供不同配置功能的支持,可以通过激活、 指定参数等方式快速切换环境

多Profile文件

我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties
默认使用application.properties的配置;
这时想激活和启动其他的环境时,就是在配置文件中指定 spring.profiles.active=dev(现在是假设我已经设置了一个application-dev.properties的环境)

spring.profiles.active=dev

person.last-name=小杨${
    
    random.uuid}
person.age=${
    
    random.int}
person.birth=2020/12/26
person.boss=false
person.maps.v1=擎天柱
person.maps.v2=28
person.lists=1,2,3
person.dog.name=${
    
    person.last-name}的狗
person.dog.age=5

yml支持多文档块方式

yml支持用三条-来分割文档,可以看下面的截图,有两个—分割文档,所以这个yml文件被分成三个文档,
最开始的文档使用

spring:
  profiles:
    active: dev

来指定激活哪一个环境
其他的环境用

spring:
  profiles: dev

来指定环境的名称
在这里插入图片描述

server:
  port: 8081
spring:
  profiles:
    active: dev

---
server:
  port: 8082
spring:
  profiles: dev

---
server:
  port: 8083
spring:
  profiles: pro

激活指定profile 的其他方式

  1. 在命令行里面进行激活
    找到项目打包成的jar包,在cmd里面运行输入的参数
    java -jar jar包的名字 --spring.profiles.active=dev;
  2. 也可以在直接测试的时候配置传入命令行参数
    在这里插入图片描述
    在这里插入图片描述
  3. 虚拟机参数
    -Dspring.profiles.active=dev
    在这里插入图片描述

配置文件加载位置

springboot 启动会扫描以下位置的application.properties或者application.yml文件
作为Spring boot的默认配置文件(file:./代表项目本身)
–file:./config/
–file:./
–classpath:/config/
–classpath:/
优先级由高到底,高优先级的配置会覆盖低优先级的配置;
SpringBoot会从这四个位置全部加载主配置文件;
而且还会形成互补配置; 互补配置就是高优先级的配置文件没有配置,就会使用低优先级的配置文件的配置

我们还可以通过spring.config.location来改变默认的配置文件位置
项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;
指定配置文件和默认加载的这些配置文件共同起作用形成互补配置;
这时候优先级最高的就是新指定的配置文件
java -jar 项目的jar包 --spring.config.location=新配置文件的位置.properties

外部配置加载顺序

SpringBoot也可以从以下位置加载配置; 优先级从高到低;
高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置

  1. 命令行参数
    所有的配置都可以在命令行上进行指定
    java -jar jar包名称 --server.port=8087 --server.context-path=/abc
    多个配置用空格分开; --配置项=值

  2. 来自java:comp/env的JNDI属性

  3. Java系统属性(System.getProperties())

    扫描二维码关注公众号,回复: 11949430 查看本文章
  4. 操作系统环境变量

  5. RandomValuePropertySource配置的random.*属性值

    由jar包外向jar包内进行寻找;
    优先加载带profile

  6. jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件

  7. jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件

    再来加载不带profile

  8. jar包外部的application.properties或application.yml(不带spring.profile)配置文件 9.jar包内部的application.properties或application.yml(不带spring.profile)配置文件

  9. @Configuration注解类上的@PropertySource

  10. 通过SpringApplication.setDefaultProperties指定的默认属性
    所有支持的配置加载来源 参考官方文档

自动配置原理

配置文件里面能写什么东西?

首先我们可以参照官方文档的附件里面的东西:官方文档
但是参照这些文档或者是根据提示都是运用皮毛而已,所以我们要明白
它的自动配置原理才是真正的懂了

自动配置原理

1.首先从开始讲起,SpringBoot在启动的时候加载主配置类,主配置类里面有一个注解
@EnableAutoConfiguration,这个注解开启了自动配置功能

2.@EnableAutoConfiguration的作用:就是利用EnableAutoConfigurationImportSelector给容器导入一些组件,具体导入什么组件的查看EnableAutoConfigurationImportSelector类
但是这个类没什么方法,还是得看它父类的方法,它的父类的public String[] selectImports(AnnotationMetadata annotationMetadata)就表明了需要导入的组件
在这里插入图片描述
可以看出里面要返回的configurations是调用方法返回的
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
进入getCandidateConfigurations
在这里插入图片描述
进入loadFactoryNames
在这里插入图片描述

所以上面是扫描所有jar包类路径下的META-INF/spring.factories文件
把扫描到的这些文件的内容包装成properties对象,步骤:
	就是先获取文件的url,然后遍历里面的每一个值
	然后String factoryClassNames = properties.getProperty(factoryClassName);
	就是从properties中获取到factoryClassName类,类名对应的值,然后把它们添加到容器中
	这里的factoryClassName传入的就是EnableAutoConfiguration.class;

	所以最终一句话就是:将类路径下的META-INF/spring.factories文件里面配置的所有EnableAutoConfiguration
	的值加入到容器之中

在这里插入图片描述
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,\
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,\
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,\
org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration,\
org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration,\
org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration

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

自动配置类是如何进行工作的呢?

现在我们以HttpEncodingAutoConfiguration这个比较简单的自动配置类来进行说明
在这里插入图片描述
是的,一大坨的,不过没关系,我们一个一个地看
首先看前面的注解

//表示这是一个配置类,和以前编写的配置文件一样,也是可以给容器添加组件
@Configuration	

//这是表示启动指定类的ConfigurationProperties功能,就是将配置文件中对应的值
//和HttpEncodingProperties绑定起来,并且把HttpEncodingProperties加入到
//IOC容器之中
@EnableConfigurationProperties({
    
    HttpEncodingProperties.class})  

//这是spring底层的@Conditional注解,这是根据不同的条件进行判断,
//如果满足指定的条件就整个配置类里面的配置生效,就比如现在,判断当前
//应用是否是web应用,如果是当前配置类生效
@ConditionalOnWebApplication

//判断当前项目有没有CharacterEncodingFilter这个类
@ConditionalOnClass({
    
    CharacterEncodingFilter.class})

//下面这个判断配置文件中的是否存在某个配置,现在是判断
//spring.http.encoding.enabled这个配置, 
//matchIfMissing = true表示如果没有也成立,
//意思就是我们无论有没有配置spring.http.encoding.enabled=true,也是默认配置了
@ConditionalOnProperty(
    prefix = "spring.http.encoding",
    value = {
    
    "enabled"},
    matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
    
    
    private final HttpEncodingProperties properties;

    public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
    
    
        this.properties = properties;
    }
	
	//这个想给容器中添加一个组件,这个组件的值需要从容器中拿,
	//这是从properties中拿的,从上面可以知道properties已经和配置文件绑定
	//而且properties在注解EnableConfigurationProperties已经加入到IOC容器中
	//而且HttpEncodingAutoConfiguration这个类只有一个有参构造器,
	//那么参数properties肯定是从容器中拿到的
    @Bean
    @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;
    }

    @Bean
    public HttpEncodingAutoConfiguration.LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() {
    
    
        return new HttpEncodingAutoConfiguration.LocaleCharsetMappingsCustomizer(this.properties);
    }

    private static class LocaleCharsetMappingsCustomizer implements EmbeddedServletContainerCustomizer, Ordered {
    
    
        private final HttpEncodingProperties properties;

        LocaleCharsetMappingsCustomizer(HttpEncodingProperties properties) {
    
    
            this.properties = properties;
        }

        public void customize(ConfigurableEmbeddedServletContainer container) {
    
    
            if (this.properties.getMapping() != null) {
    
    
                container.setLocaleCharsetMappings(this.properties.getMapping());
            }

        }

        public int getOrder() {
    
    
            return 0;
        }
    }
}

根据当前不同的条件判断让不让这个配置类生效,
如果生效这个配置类就会给容器中添加不少的组件,这些组件的属性是从对应的properties类中获取,而这些类的属性的值又是从配置文件中获取过来的

上面对应的HttpEncodingProperties类
所以所有在配置文件中的能配置的属性都是在xxxProperties类中封装着,配置文件中能配置什么就可以参照某个功能对应的这个属性类,比如上面的HttpEncodingProperties,就是HTTP编码自动配置

//这个注解不就是从配置文件中获取指定的值和bean的属性进行绑定的吗?
//然后它还指定了前缀是spring.http.encoding的,
//类里面有什么属性我们就可以配置什么属性
//比如有charset属性,就可以配置spring.http.encoding.charset=utf-8
@ConfigurationProperties(
    prefix = "spring.http.encoding"
)
public class HttpEncodingProperties {
    
    
    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
    private Charset charset;
    private Boolean force;
    private Boolean forceRequest;
    private Boolean forceResponse;
    private Map<Locale, Charset> mapping;

    public HttpEncodingProperties() {
    
    
        this.charset = DEFAULT_CHARSET;
    }

    public Charset getCharset() {
    
    
        return this.charset;
    }

    public void setCharset(Charset charset) {
    
    
        this.charset = charset;
    }
   ........................

@Conditional

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;
@Conditional扩展出来的注解有
在这里插入图片描述
自动配置类要在指定的条件下才能生效的,所以EnableAutoConfiguration的那么自动配置类很多没有加载呢,但是应该也有很多加载了,那么我们如何知道哪一些加载了呢?
现在我们就得在spring boot的配置文件中启动debug模式,就是在配置文件中写上debug=true就是,这样控制台就会输出那些自动配置类生效,哪些没有生效
比如


=========================
AUTO-CONFIGURATION REPORT
=========================


Positive matches:(生效的)
-----------------

   DispatcherServletAutoConfiguration matched:
      - @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
      - @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)

Negative matches:(没有生效的)
-----------------

   ActiveMQAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)

配置原理总结

首先springboot启动的时候会加载大量的自动配置类
我们看我们需要的功能呢有没有springboot默认写好的自动配置类
我们再看这个自动配置类中配置了哪一些组件
自动配置类给容器中添加组件的时候,会从properties类中获取出来某些属性,
而properties类的属性又和配置文件绑定,所以我们可以在配置文件中指定这些属性

猜你喜欢

转载自blog.csdn.net/qq_43416157/article/details/107860891