SpringBoot使用一个全局的配置文件,配置文件名是固定的:
修改SpringBoot自动配置的默认值,因为在所有的自动配置类中他们都会去读取我们的配置文件,如果说有配置这些项目就按照我们配置的,没有则使用自动配置。 支持两种格式,我们主要说说后面一种,前面比较简单就是采用的点的方式定义的。yml 其实也是一种标记语言,YAML 他的语法比较简洁,写起来没有 xml 那么臃肿。
k:(空格)v:表示一对键值对(空格必须有)
以空格的缩进来控制层级关系;只要是左对齐的一列数据,都是同一个层级的同时属性和值也是大小写敏感;
k: v:字面直接来写,字符串默认不用加上单引号或者双引号;
k: v:在下一行来写对象的属性和值的关系;注意缩进
对象还是k: v的方式
friends: lastName: zhangsan age: 20 |
---|
行内写法:
friends: {lastName: zhangsan,age: 18} |
---|
用- 值表示数组中的一个元素
pets: - cat - dog - pig |
---|
行内写法
pets: [cat,dog,pig] |
---|
配置文件
person: lastName: hello age: 18 boss: false birth: 2017/12/12 maps: {k1: v1,k2: 12} lists: - lisi - zhaoliu dog: name: 小狗 age: 12 |
---|
Bean:
/** * 将配置文件中配置的每一个属性的值,映射到这个组件中 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定; * prefix = "person":配置文件中哪个下面的所有属性进行一一映射 * * 只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能; * */@Component@ConfigurationProperties(prefix = "person")public class Person { private String lastName; private Integer age; private Boolean boss; private Date birth; private Map<String,Object> maps; private List<Object> lists; private Dog dog; |
---|
在导入配置文件处理器以后,编写配置就有提示了。
<!--导入配置文件处理器,配置文件进行绑定就会有提示--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> |
---|
一个小问题就是配置文件中配置的中文读出来会乱码,这主要是 idea 的 properties 文件默认采用的 utf-8 ,我们需要使用自动转 ascii 码。
SpringBoot推荐给容器中添加组件的方式,推荐使用全注解的方式
/** * @Configuration:指明当前类是一个配置类;就是来替代之前的Spring配置文件 * * 在配置文件中用<bean><bean/>标签添加组件 * */@Configurationpublic class MyAppConfig { //将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名,也可以自己指定。 @Bean public HelloService helloService02(){ System.out.println("配置类@Bean给容器中添加组件了..."); return new HelloService(); }} |
---|
我们在主配置文件编写的时候,文件名可以是application-{profile}.properties/yml
默认使用application.properties
的配置;
server: port: 8081spring: profiles: active: prod---server: port: 8083spring: profiles: dev---server: port: 8084spring: profiles: prod #指定属于哪个环境 |
---|
java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev;
可以直接在测试的时候,配置传入命令行参数-Dspring.profiles.active=dev
所有的配置都可以在命令行上进行指定
java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/abc
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
获取候选的配置
SpringFactoriesLoader.loadFactoryNames()
扫描所有jar包类路径下 META-INF/spring.factories
把扫描到的这些文件的内容包装成 properties
对象,从 properties
中获取到 EnableAutoConfiguration.class
类(类名)对应的值,然后把他们添加在容器中
总之一句话将类路径下 META-INF/spring.factories 里面配置的所有EnableAutoConfiguration的值加入到了容器中 如下:
# Auto Configureorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ |
---|
每一个这样的 xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中,用他们来做自动配置
//表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件@Configuration //启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到ioc容器中@EnableConfigurationProperties(HttpEncodingProperties.class) //Spring底层@Conditional注解,根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效,判断当前应用是否是web应用,如果是,当前配置类生效@ConditionalOnWebApplication //判断当前项目有没有这个类CharacterEncodingFilter,SpringMVC中进行乱码解决的过滤器;@ConditionalOnClass(CharacterEncodingFilter.class) //判断配置文件中是否存在某个配置 spring.http.encoding.enabled;如果不存在,判断也是成立的,也就是说即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true) public class HttpEncodingAutoConfiguration { //他已经和SpringBoot的配置文件映射了 private final HttpEncodingProperties properties; //只有一个有参构造器的情况下,参数的值就会从容器中拿 public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) { this.properties = properties; } @Bean //给容器中添加一个组件,这个组件的某些值需要从properties中获取 @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; } |
---|
根据当前不同的条件判断,决定这个配置类是否生效,一但这个配置类生效,这个配置类就会给容器中添加各种组件,这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的。 也就是如下两个类非常重要: