YAML基本语法

  • 使用缩进表示层级关系
  • 缩进时不允许使用 tab 键,只允许使用空格
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
  • 大小写敏感
  • 语法参考文档

YAML支持的数据结构

  • 对象(属性和值)、Map(键值对):键值对的集合

    1. 对象的一组键值对,使用冒号分隔。username: admin
    2. 冒号后面跟空格来分开键和值

      person:
        name: kate
        age: 20
  • 数组(List、Set):一组按次序排列的值

    1. 以 - 开头的行,构成一个数组

      scores:
        - 21
        - 23
        - 24
  • 字面量:单个的、不可再分的值

    1. 数字、布尔、日期
    2. 字符串

      1. 默认不使用引号
      2. 可以使用单引号或者双引号,单引号会转义特殊字符
          例如:name: "123 \n lisi";则输出: 123 换行 lisi
      3. 字符串可以写成多行,从第二行开始,必须有一个单空格缩进,换行符会被转为空格
          例如:name: '123 \n lisi';则输出:123 \n lisi
  • 复合类型数据

    person:
      name: hello
      age: 18
      birth: 2017/12/12
      maps:
        school: aa
        class: bb
      lists:
        ‐ lisi
        ‐ zhaoliu
      dog:
        name: 小狗 
        age: 12

程序中使用YAML

通过yaml文件实例化bean

(1) application.yaml文件

person:
      age: 18
      birth: 2017/12/12
      maps:
        school: aa
        class: bb
      lists:
        - lisi
        - zhaoliu
      name: hello

(2) 实体类:Person.java

@Data
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String name;
    private Integer age;
    private String birth;
    private Map<String, String> maps;
    private List<String> lists;
}

(1)@ConfigurationProperties 作用是告诉 spring boot 将该注解标注的类的属性和配置文件中相关配置绑定。prefix = "person" 的作用是配置文件中的那个配置映射。使用该注解的前提条件是容器中已经注入了@ConfigurationProperties注解标注的类;@ConfigurationProperties 默认从全局配置文件中获取配置

(2)@PropertySource、@ImportResource 于@ConfigurationProperties 有何区别?

  • @PropertySource : 加载类路径下指定的配置文件,如:@PropertySource(value = "classpath:db.properties")
  • @ImportResource : 导入spring的配置文件,让配置文件里面的内容生效,如:@ImportResource(locations={"classpath:spring-beans.xml"})标注在spring boot住配置类上

(3) spring boot单元测试

@RunWith(SpringRunner.class)
@org.springframework.boot.test.context.SpringBootTest
public class SpringBootTest {
    @Autowired
    private Person person;

    @Test
    public void testPerson() {
        System.out.println(person);
    }
}

(4) YAML配置文件处理器
导入配置文件处理器依赖,配置文件进行绑定就会有提示

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring‐boot‐configuration‐processor</artifactId>
</dependency>

引入后的效果是在 .yaml文件中可看到:
clipboard.png

配置文件的加载位置

springboot 启动会扫描以下位置的 application.properties 或者 application.yml文件作为spring boot的默认配置文件:

  • /Users/shifeifei03/Documents/Project/my-project/spring-boot/config/
  • /Users/shifeifei03/Documents/Project/my-project/spring-boot/
  • /Users/shifeifei03/Documents/Project/my-project/spring-boot/spring-boot-helloword/src/main/resources/config/config/
  • /Users/shifeifei03/Documents/Project/my-project/spring-boot/spring-boot-helloword/src/main/resources/

优先级由高到底,高优先级的配置会覆盖低优先级的配置

自动配置原理

  • springBoot 启动加载主配置类时,利用 @EnableAutoConfiguration 开启了自动配置功能
  • @EnableAutoConfiguration 注解的作用

    • 利用 AutoConfigurationImportSelector 组件选择器给容器中导入诸多组件,查看源码可知:主要是利用了该组件选择器的 String[] selectImports(AnnotationMetadata annotationMetadata) 方法:

clipboard.png

clipboard.png

clipboard.png

clipboard.png

  • HttpEncodingAutoConfiguration 为例来看看自动配置过程
//标注一个配置类
@Configuration
/**
 *spring boot启动动指定类的ConfigurationProperties功能;将配置文件中对应的值和
 *HttpProperties绑定起来;并把HttpProperties加入到容器中
 */
@EnableConfigurationProperties(HttpProperties.class)
/**
 *如果满足指定的条件,整个配置类里面的配置就会生效; 判断当前应用是否是web应用?如果是,当前配置 
 *类生效
 */
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
//判断当前应用中有没有haracterEncodingFilter这个类,有则配置生效
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
    
    /**
     * HttpProperties 和 spring boot 的配置文件映射了,原因是:HttpProperties 被 
     * @ConfigurationProperties 注解标注
     * @ConfigurationProperties(prefix = "spring.http")
     * public class HttpProperties {}
     */
    private final HttpProperties.Encoding properties;

    public HttpEncodingAutoConfiguration(HttpProperties properties) {
        this.properties = properties.getEncoding();
    }

    //给容器中添加一个组件,组件的某些值需要从properties文件中获取
    @Bean
    @ConditionalOnMissingBean
    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 LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() {
        return new LocaleCharsetMappingsCustomizer(this.properties);
    }
}

@Conditional派生注解的了解

spring中@Conditional中的作用是满足某一个特定条件创建时给容器中添加一个特定的 bean

@Conditional扩展注解 作用(判断是否满足当前指定条件)
@ConditionalOnJava 系统的java版本是否符合要求
@ConditionalOnBean 容器中存在指定Bean
@ConditionalOnMissingBean 容器中不存在指定Bean
@ConditionalOnExpression 满足SpEL表达式指定
@ConditionalOnClass 系统中有指定的类
@ConditionalOnMissingClass 系统中没有指定的类
@ConditionalOnSingleCandidate 容器中只有一个指定的Bean,或者这个Bean是首选Bean
@ConditionalOnProperty 系统中指定的属性是否有指定的值
@ConditionalOnResource 类路径下是否存在指定资源文件
@ConditionalOnWebApplication 当前是web环境
@ConditionalOnNotWebApplication 当前不是web环境
@ConditionalOnJndi JNDI存在指定项

spring boot 自动配置精髓

  • spring boot启动会加载大量的自动配置类
  • 可以从spring boot自动配置类中找到我们需要使用的功能
  • 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在application.properties配置文件中指定这些属性的值,覆盖配置类中的默认值
  • 记住:

    • xxxxAutoConfigurartion : 自动配置类,给容器中添加组件
    • xxxxProperties : 封装配置文件中相关属性
  • spring boot属性配置项参考

一只小小鸟
144 声望25 粉丝

如何做一个深层次的思考者,从简单开始、从记录开始。