1. Spring Boot的全局配置文件要求
(1) application.properties / application.yml,二选一,但 名字必须固定为application※
(2) 存放于src/main/resources目录或者classpath:config下
(3) 显式指定Spring Boot自动配置项以覆盖默认值
2.yml -> YAML
YAML Ain’t Markup Language
(1) YAML不是绝对的标记语言:A+isn’t
(2) 以数据为中心 ,比JSON和xml更适合作配置文件
(3) 基本语法
<1> key:(空格)value,表示一个键值对(※空格必须有且不允许使用Tab制表)
<2> 空格缩进控制层级关系(只要左对齐的一列属性都属于同一层级),Python式层级缩进
<3> key和value大小写敏感
(4)value的表示
类型 | 说明 |
---|---|
字面量:数字、字符串、布尔值 | 空格后直接书写 字符串默认不加单双引号 双引号”“:不会转义字符串里的特殊字符,特殊字符仍然表示原本的特殊意思。比如name: "zhangsan \n lisi"输出结果是zhangsan (换行)lisi 单引号’’:转义特殊字符,特殊字符只是一个普通的字符串部分。相同的例子,输出zhangsan \n lisi |
对象:Object-Map(键值对) | 使用缩进嵌套"属性和值"的键值对 普通写法: ![]() 行内写法: ![]() |
数组,Collections | 使用 - value 表示集合中的一个元素 普通写法: ![]() 行内写法: ![]() |
以上基本用法可以组合出非常复杂的结构,比如一个对象内包含了其他类、对象列表、Map<String,Object>等(组合是任意的,Map里面可以再放Map,只要是缩进正确的键值对即可)。值得注意的是,每一属性行的末尾不需要逗号。在IDEA中,可以通过yml文件下方的层级提示来确定嵌套层级是否正确。
(5) 配置文件中的动态占位符${}
项目 | 说明 |
---|---|
随机数 | ${random.value}, ${random.int}, ${random.long}, ${random.int(10)}, ${random.int[1024,65536]} |
已配置的属性 | 引用先前配置过的属性:${app.name:默认值},找不到app的属性值name时使用默认值(默认值并不是必须的) |
3.如何将配置文件中的属性值注入到与之对应的JavaBean
3.1 准备
-
配置文件
yaml格式(application.yml)person: lastName: zhangsan age: 18 boss: false birthday: 2017/12/12 maps: {k1: v1,k2: v2} lists: - lisi - zhaoliu dog: name: 小狗 age: 2
properties格式(application.properties)
###注意.:properties文件使用的ASCii编码,IDEA默认使用的是UTF-8,会导致中文乱码。 ###解决:File->Setting->Editor->File Encoding,Default encoding for properties files: UTF-8 并勾选 Transparent native-to-ascii conversion。 person.last-name=zhangsan person.age=18 person.birthday=2017/12/15 person.boss=false ###map中的entry表示### person.maps.k1=v1 person.maps.k2=v2 ###用逗号分隔表示列表### person.lists=a,b,c ###属性连点### person.dog.name=dog person.dog.age=2
-
JavaBean
/** * 将配置文件中预置的属性值注入到组件@Component中 * @ConfigurationProperties告诉SpringBoot将本类中的所有属性字段和配置文件中相应的属性键值对进行映射绑定 *使用注解属性prefix指定映射配置项前缀。也就是配置文件中哪一个名字层级的所有属性进行一一映射,类似@Resource */ @ConfigurationProperties(prefix = "pserson") /** * 只有这个Bean是IoC容器中的组件,才能使用容器的功能(比如使用@ConfigurationProperties进行快速映射绑定),值得注意。 */ @Component public class Person { private String lastName; private Integer age; private boolean boss; private Date birthday; private Map<String,Object> maps; private List<Object> lists; private Dog dog; //... }
补充:可以导入 “配置文件提示”组件的依赖,在yml文件中输入时将自动提示可配置字段名。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
提示的两个单词之间用连字符"-"连接,但与Mybatis的命名规则一样可以自动匹配JavaBean驼峰命名规范,也就是说last-name与lastName时一样的。
3.2 Spring Boot配置文件映射绑定的相关总结
-
只有这个Bean是IoC容器中的组件,才能使用容器的功能(比如使用@ConfigurationProperties进行快速映射绑定),值得注意。
-
@ConfigurationProperties告诉SpringBoot将本类中的所有属性字段和配置文件中相应的属性键值对进行映射绑定。使用注解属性prefix指定映射配置项前缀。也就是配置文件中哪一个名字层级的所有属性进行一一映射,类似@Resource。
-
Spring的底层注解@Value也可以实现类似功能,与@ConfigurationProperties的比较如下
\ @ConfigurationProperties @Value 功能 批量注入配置文件中的预置属性 手动一个个给属性标注@Value(${…})指定 松散绑定(Relaxed Binding,松散语法):
大小写驼峰命名(如lastName), _(下划线连接如last_name), -(连字符连接如last-name)支持,可以识别 不支持,配置文件和注解标识必须完全一样 SpEL,形式如#{…}的Spring表达式语言 不支持 支持 JSR303校验 支持
类前标注@Validated,字段校验与SpringMVC中学习的一致不支持 复杂类型封装如Map 支持 不支持,只能取简单值 因此,如果只是在某业务逻辑中需要获取配置文件中的某项简单的值,就用@Value,而专门编写JavaBean来与配置文件映射绑定的情况都直接使用@ConfigurationProperties。
4. @PropertySource 和 @ImportResource
(1) @PropertySource:加载指定的自定义properties,而非来自全局配置文件application.properties(默认情况全部从全局配置文件中读取)。注意,该注解与@ConfigurationProperties并不互斥,反而需要结合使用。
@PropertySource(value={"classpath:person.properties"})
@ConfigurationProperties(prefix="person")
@Component
public class Person{...}
(2) @ImportResource:标注在某个配置类上,导入Spring的配置文件,使其生效。(之前手写的配置文件applicationContext.xml,在Spring Boot中不会自动识别加载)但在实际Spring Boot开发中,不会通过这种方式导入组件。
@ImportResource(locations={"classpath:applicationContext.xml"})
//之前有说过,其底层有一个@SpringBootConfiguration,是一个配置类注解
@SpringBootApplication
public class HelloWorld{...}
5. Spring Boot推荐向容器中添加组件的方式:全注解
Spring配置文件applicationContext.xml ==升级==> SpringBoot全注解配置类
注意: 只要标注了@Configuration的class,都是配置类,配置类的数量是任意的
/**
* @Configuration指名当前类是一个配置类,代替Spring配置文件ApplicationContext.xml.
* (只要标注了@Configuration的,都是配置类,配置类的数量是任意的)
*
* 在配置文件中用<bean></bean>添加组件==>@Bean
* 标注@Bean方法的返回值被加入IOC容器中,其默认id是这个方法名
*
*/
@Configuration
public class MyAppConfig {
@Bean
public HelloService helloService(){
System.out.println("给IOC容器添加组件");
return new HelloService();
}
}
4. 根据运行环境切换不同的配置文件:Profile
4.1 第一种方式:多profile文件
编写多个“文件名特殊”配置文件,文件名格式:application-{ENV_PROFILE_NAME}.properties/yml,如application-dev.properties / application-prod.properties
【默认使用的是主配置文件application.properties/yml】
4.2 第二种方式(仅yml):多文档块(Documents)方式
在主配置文件application.yml中使用"—"进行文档分块(IDEA在yml文件下方有导航Document 1/n)
server:
port: 8081
#指定激活的环境
spring:
profiles:
active: dev
---
server:
port: 8082
#所属环境的标识
spring:
profiles: dev
---
server:
port: 8083
spring:
profiles: prod
3. 激活指定环境profile
- 在主配置文件application.properties中指定spring.profiles.active,如spring.profiles.active=dev
- 在主配置文件application.yml中指定spring: profile: active:, 如spring: profile: active: dev
- 使用命令行参数(Run Configurations -> Program arguments 或 CMD启动打包后的jar) --spring.profiles.active=dev
- 虚拟机参数(Run Configurations -> VM Options) --Dspring.profiles.active=dev
5. 全局配置文件的加载位置及顺序
- Spring Boot启动时会扫描以下位置的application.properties / application.yml作为默认全局配置文件。
file:./config/ 但注意Maven在打包时,只会将main>java和resource打jar包,工程路径下file:./config/和file:./的主配置文件并不会在jar包内,因此在target下启动java -jar,这两个地方的主配置文件是无效的
file:./
classpath:/config/
classpath:/
【以上优先级从高到低,这四个位置的所有的application.properties/yml都会被加载,高优先级配置项会覆盖低优先级配置项(形成互补配置)】 - 项目打包后,可以在java -jar命令中使用参数–spring.config.location来改变默认配置的位置,在启动项目时指定配置文件的新位置, 该参数指定的配置文件(优先级最高)和默认加载的配置文件会共同起作用,形成互补配置(经常在运维过程中使用)
6. 外部配置加载顺序
Spring Boot也可以从以下位置加载配置:优先级从高到底,高优先级的配置会覆盖低优先级的配置,所有的配置会形成互补配置。
(1)命令行参数,最高优先级,适合少量参数的覆盖。–ARGNAME=ARGVALUE,多个参数用空格分隔,如java -jar spring-boot-02-0.0.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/abc
(2)来自java:comp/env的JNDI属性
(3)Java系统属性(System.getProperties())
(4)操作系统的环境变量
(5)RandomValuePropertySource配置的random.*属性值
(6)包外(和jar包处于同一文件夹)向包内寻找主配置文件,适合大规模覆盖参数。
优先加载profile
jar包外部的application-{profile}.properties / application.yml(带spring.profile)的配置文件
jar包内部的application-{profile}.properties / application.yml(带spring.profile)的配置文件
再加载非profile
jar包外部的application.properties或application.yml(不带spring.profile)配置文件
jar包内部的application.properties或application.yml(不带spring.profile)配置文件
(7)@Configuration注解类上的PropertySource
(8)通过SpringApplication.setDefaultProperties指定的默认属性值
7. 自动配置原理
7.1 核心过程
- Spring Boot启动时加载 主配置类,开启自动配置功能 @EnableAutoConfiguration
@SpringBootApplication(主配置类标识) |---@SpringBootConfiguration(声明一个配置类) |---@EnableAutoConfiguration(启用自动配置功能) |--@AutoConfigurationPackage(扫描主配置类所在包及子包下的所有组件) |--@Import(EnableAutoConfigurationImportSelector.class)(这是自动配置的核心起点,xxxAutoConfiguration组件被导入到容器中)
- @EnableAutoConfiguration的核心(完整的源码参照入门篇):
利用EnableAutoConfigurationImportSelector的父类方法selectImports(),其中关键代码如下
Spring Boot扫描所有spring-boot-xxx.jar类路径下的META-INF/spring.factories,将扫描到文件内容包装为Properties对象,从中获取到EnableAutoConfiguration.class的全类名对应的值(这就是spring-boot-autoconfigure.jar/META-INF/spring.facotires),之后把它们加入容器中:public String[] selectImports(AnnotationMetadata annotationMetadata) { //... //获取候选的配置 List<String> configurations = getCandidateConfigurations(annotationMetadata,attributes); //... } //向下一层,getCandidateConfigurations protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { //传递了两个参数,第一个点进去是EnableAutoConfiguration.class,第二个点进去是classLoader List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()); //... } //再向下一层,loadFactoryNames public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) { String factoryClassName = factoryClass.getName(); try { //这里就指明了获取列表的位置,所有jar包类路径下META-INF/spring.factories 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(); //遍历每一个url,转换为一个Properties,拿到factoryClassName指定的value Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url)); //这个factoryClassName就是传过来EnableAutoConfiguration.class类名 String factoryClassNames = properties.getProperty(factoryClassName); //... }
每一个这样的xxxAutoConfiguration类都是容器中的一个组件,都会被加入到容器中,由它们再完成自动配置工作。# 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.CassandraReactiveDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\ 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.MongoReactiveDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\ 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.RedisReactiveAutoConfiguration,\ 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.flyway.FlywayAutoConfiguration,\ 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.http.HttpMessageConvertersAutoConfiguration,\ org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\ org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\ 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.groovy.template.GroovyTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\ org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\ org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\ 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.mongo.embedded.EmbeddedMongoAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\ org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\ org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\ org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\ org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,\ org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\ org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\ org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\ org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\ org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\ org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\ org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\ org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientAutoConfiguration,\ 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.client.RestTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\ org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\ org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\ org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\ org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\ org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\ org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\ org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\ org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\ org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\ org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\ org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration
- 每一个xxxAutoConfiguration类组件会进行对应的自动配置功能,以HttpEncodeAutoConfiguration为例
根据当前不同的条件判断(@ConditionalOnxxx),决定自动配置类(@Configuration)是否生效(作为容器中的组件)。一旦生效,该配置类就会给容器中添加各种组件(@Bean),这些组件需要的值将从对应的xxxProperties中获取(由@EnableConfigurationProperties之前导入),而对应的xxxProperties中的每一个字段又是已经和配置文件绑定的(@ConfigurationProperties)。//表示该类是一个配置类,对应以前编写的配置文件,启动时容器添加该组件 @Configuration //启动指定类的ConfigurationProperties功能,HttpEncodingProperties(推广至所有xxxProperties)标注了@CondigurationProperties,即从配置文件中获取前缀指定的值和JavaBean(也就是HttpEncodingProperties)字段进行绑定,之后把HttpEncodingProperties加入IOC容器中备用 @EnableConfigurationProperties({HttpEncodingProperties.class}) //SpringBoot所有的@ContionalOnXXX都是调用Spring底层@Conditional(OnCondition.class),根据不同的条件进行判断,若满足指定条件,当前被标注的整个配置类中的配置才会生效 //判断当前应用是否为Web应用,若是则自动配置生效 @ConditionalOnWebApplication( type = Type.SERVLET ) //判断当前项目中是否存在指定类CharacterEncodingFilter.class @ConditionalOnClass({CharacterEncodingFilter.class}) //判断配置文件中是否存在指定的配置 spring.http.encoding.enabled; //属性matchIfMissing=true表示,若配置文件不存在指定配置spring.http.encoding.enabled,判断仍然成立(即默认生效) @ConditionalOnProperty( prefix = "spring.http.encoding", value = {"enabled"}, matchIfMissing = true ) public class HttpEncodingAutoConfiguration{ //已经和SpringBoot的配置文件映射 private final HttpEncodingProperties properties; //只有一个有参构造器的情况下,就会从容器中取出形参需要的对象(HttpEncodingProperties早前已经被@EnableConfigurationProperties加入到容器中了) public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) { this.properties = properties; } //使用@Bean向IOC容器中添加组件characterEncodingFilter,该组件的某些值需要从properties中取出 @Bean //检查容器中是否已存在相应组件,若不存在则创建=>单例保证 @ConditionalOnMissingBean public CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter(); filter.setEncoding(this.properties.getCharset().name()); filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpEncodingProperties.Type.REQUEST)); filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpEncodingProperties.Type.RESPONSE)); return filter; } }
注:所有在配置文件中的可配置项都被xxxProperties封装为属性,在全局配置文件中能配置哪些值都是来源某个功能对应的xxxProperties类。
7.2 其他细节
- @ConditionalOnXXX
Spring Boot所有的@ConditionalOnXXX都是调用Spring底层@Conditional(OnCondition.class),根据不同的条件进行判断,若满足指定条件,当前被标注的配置类才会生效
- 自动配置报告:当前哪个自动配置类生效(因为自动配置类必须在一定的条件下生效)
在全局配置文件application.properties中开启Spring Boot的debug模式,控制台将打印“自动配置报告”,可以方便地知道哪些自动配置类生效debug=true
============================ CONDITIONS EVALUATION REPORT ============================ Positive matches: ----------------- CodecsAutoConfiguration matched: - @ConditionalOnClass found required class 'org.springframework.http.codec.CodecConfigurer'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition) CodecsAutoConfiguration.JacksonCodecConfiguration matched: - @ConditionalOnClass found required class 'com.fasterxml.jackson.databind.ObjectMapper'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition) Negative matches: ----------------- ActiveMQAutoConfiguration: Did not match: - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition) AopAutoConfiguration: Did not match: - @ConditionalOnClass did not find required classes 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice', 'org.aspectj.weaver.AnnotatedElement' (OnClassCondition)