Spring Boot Notes

19-04-14 编程 #code #spring

一些容易忘记的 spring boot 知识要点。

注意,.yaml 和.yml 文件没任何区别。

配置

SpringBootApplication 注解

@SpringBootApplication
// <=等价=>
@Configuration
@ComponentScan
@EnableAutoConfiguration

自动配置

spring 的自动配置依赖以下注解:

spring-boot-autoconfig-conditional

配置文件

任何时候硬编码的配置总是不好的,spring 支持从很多环境中读取配置:配置文件,yaml 文件,环境变量,命令参数。
配置可以在@Value注解中使用,也可Environment访问,或者通过@ConfigurationProperties将配置属性绑定到特定的 bean(例子).

spring boot 的配置属性读取顺序为:

因为 spring-boot 主要使用的application.properties/yaml文件,所以后面主要关注这个文件。

此外,spring 代码中使用了大约近千个 (300 多类) 默认值,这些默认值都是可以覆盖的。只需你在你的 propeties/yaml 文件中用相同的 key 即可。
所有的参考值见:example application.properties

application.properties

SpringApplication loads properties from application.properties files in the following locations and adds them to the Spring Environment:

application.yml

yaml 是 json 的超集,相比 properties 文件,有着简洁灵活的优势 例如可以设置数组,设置 group 概念等。
yaml 文件可以配置数组:

# 数组功能,等价
# my.servers[0]=dev.bar.com
# my.servers[1]=foo.bar.com
my:
   servers:
       - dev.bar.com
	   - foo.bar.com

#上面的配置可以通过注解绑定到以下 bean 中,非常强大。
@ConfigurationProperties(prefix="my")
public class Config {
	private List<String> servers = new ArrayList<String>();
}


# 在一个 yaml 文件设置不同的 profile 配置,properties 文件只能通过拆分文件`application-profiles.properties`实现。
server:
    address: 192.168.1.100
---
spring:
    profiles: DEV
server:
    address: 127.0.0.1
---
spring:
    profiles: PRD
server:
    address: 192.168.1.120

yaml 缺点:

YAML files cannot be loaded by using the @PropertySource annotation. So, in the case that you need to load values that way, you need to use a properties file.

当然使用 properties 文件缺点也明显,不能分组 (yaml 的—功能);同时中文显示容易 unicode 码。

读取配置文件

除了 application.properties 文件,其他的配置属性文件需要我们自己加载读取。注意,下面的PropertySource无法加载 yaml 文件。

使用 PropertySource

cron=0/3 * * * * ?
@Configuration
@PropertySource("classpath:foo.properties")
public class PropertiesWithJavaConfig {
    @Value(${cron})
    private String cron;
    
}

//or
@PropertySource({ 
  "classpath:persistence-${envTarget:mysql}.properties"
})

//multi files
//java 8+
@PropertySource("classpath:foo.properties")
@PropertySource("classpath:bar.properties")
public class PropertiesWithJavaConfig {
    //...
}
//java 6+
@PropertySources({
    @PropertySource("classpath:foo.properties"),
    @PropertySource("classpath:bar.properties")
})
public class PropertiesWithJavaConfig {
    //...
}

//通过 xml 加载
//register file in xml
<context:property-placeholder location="classpath:foo.properties" />
//foo.properties in src/main/resources
<context:property-placeholder location="classpath:foo.properties, classpath:bar.properties"/>

如何加载自定义的 yaml 文件

上面提到 spring 会默认加载application.yml文件的配置。但是其他文件名的 yml 文件无法通过@PropertySource加载。可以有以下方法。

使用 yaml 文件的加载可以通过ConfigurationProperties绑定到配置 bean 中。还要添加 2 个注解注册到 spring:

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties
public class YAMLConfig {
  
    private String name;
    private String environment;
    private List<String> servers = new ArrayList<>();
 
    // standard getters and setters
}
spring:
    profiles: prod
name: prod-YAML
environment: production
servers: 
    - www.abc.com
    - www.xyz.com

profiles

很多配置希望基于环境,spring boot 支持application-profile.properties格式的配置,profile 可以是 DEV,ST,UAT,PRD,TEST 等。
例如某个 class 希望只有在PRD环境才有:

@Profile("PRD")
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {}

然后在application.yml/properties设置 profile:

spring:
  profiles:
    active: PRD

properties 文件设置 profile

application.properties文件只能使用application-DEV.properties,application-ST.properties设置 profile.

yml 文件设置 profile

application.yml既可以像 properties 文件使用application-DEV.yml来设置 profile,也可以使用---分组。如下示例,logging.level=INFO在所有 profile 中生效,而在生产环境中增加日志文件设置,DEV 环境则使用DEBUG级别日志。

# application.yml
logging:
  level:
   root: INFO
---
spring:
  profiles: DEV
logging:
  level:
    root: DEBUG
---
spring:
  profiles: PRD
logging:
  path: /tmp/
  file: BookWorm.log
  level:
    root: WARN

激活 profiles

application.yml/properties文件中激活某个 profile:

spring:
    profiles:
        active: DEV

如果你设置了SPRING_PROFILES_ACTIVE环境变量,那么会覆盖上面的 profile 设置。当然你也可以使用自定义环境变量和默认值:

spring:
    profiles:
        active: ${ENV_TYP:PRD}
# 读取 ENV_TYP 环境变量的值作为激活 profile,如果没用这个环境变量,那么设置为 PRD.

测试