Profile功能
在开发中可能遇到生产环境、测试环境、开发环境等,这些环境中的配置都是不一样的,而SpringBoot的profile功能可以快速的实现环境的切换。
创建SpringBoot配置文件,注意命名规则:application-xxx.yaml,而xxx所需要填的是环境的名称,例如小黄有一个生产环境prod,一个测试环境test,那么我可以这样创建两个环境的配置文件application-prod.yaml,application-test.yaml
生产环境配置
person:
name: 张三
age: 18
server:
port: 8888
测试环境配置
person:
name: 张三测试啦
age: 21
server:
port: 7777
我们可以在application.properties文件下对环境进行配置,例如我需要使用测试环境,这样服务启动应用的是测试环境的配置
spring.profiles.active=test
@Data
@Component
@ConfigurationProperties("person")
public class Person {
private String name;
private Integer age;
}
@RestController
public class HelloController {
@Value("${person.name:李四}")
String name;
@Autowired
Person person;
@GetMapping("/")
public Person hello(){
return person;
}
}
除了在配置文件中设置之外,打包好项目搭建在服务器上准备启动时,也还是可以通过命令行更改环境,通过–来设置配置文件的值,命令如下
java -jar boot-04-web-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
@Profile自动配置
我们可以通过在类上标注@Profile注解,来告诉服务器使用哪个类
我们希望创建自动装配person对象,在生产环境是boss对象,在测试环境是Emp对象
public interface Person {
String getName();
Integer getAge();
}
@Profile("prod")
@Data
@Component
public class Boss implements Person{
private String name;
private Integer age;
}
@Profile("test")
@Data
@Component
public class Emp implements Person{
private String name;
private Integer age;
}
@RestController
public class HelloController {
@Value("${person.name:李四}")
String name;
@Autowired
Person person;
@GetMapping("/")
public String hello(){
return person.getClass().toString();
}
}
profile分组
我们可以将多个配置文件绑定在同一个分组里,不同的属性会相互结合,例如prod只设置了name,ppd设置了age,输出将两者合并,如果属性冲突,引用下标值大的属性
spring.profiles.active=mytest
spring.profiles.group.myprod[0]=prod
spring.profiles.group.myprod[1]=ppd
spring.profiles.group.mytest[0]=test
外部化配置
-
SpringBootTest
and the test annotations for testing a particular slice of your application. -
@TestPropertySource
annotations on your tests. -
Devtools global settings properties in the
$HOME/.config/spring-boot
directory when devtools is active.
1、外部配置源
常用:Java属性文件、YAML文件、环境变量、命令行参数;
2、配置文件查找位置
(1) classpath 根路径
(2) classpath 根路径下config目录
(3) jar包当前目录
(4) jar包当前目录的config目录
(5) /config子目录的直接子目录
3、配置文件加载顺序:
-
当前jar包内部的application.properties和application.yml
-
当前jar包内部的application-{profile}.properties 和 application-{profile}.yml
-
引用的外部jar包的application.properties和application.yml
-
引用的外部jar包的application-{profile}.properties 和 application-{profile}.yml
4、指定环境优先,外部优先,后面的可以覆盖前面的同名配置项
自定义starter
模仿其他第三方的starter,都是通过一个启动器引入的,创建两个工程
yellowstar-hello-spring-boot-starter 启动器
yellowstar-hello-spring-boot-starter-autoconfigure 自动配置包
启动器中只需要引入自动配置包的依赖即可
在自动配置包中,我们创建一个helloservice类,注意这个类不需要自动注入
public class HelloService {
@Autowired
HelloProperties helloProperties;
public String sayHello(String username){
return helloProperties.getPrefix() + ": HELLO " + username + " -> " + helloProperties.getSuffix();
}
}
HelloProperties
HelloProperties用来定义属性,已经对设置属性值的名称做一个要求
@ConfigurationProperties("yellowstar.hello")
public class HelloProperties {
String prefix;
String suffix;
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
}
HelloServiceAutoConfiguration
HelloServiceAutoConfiguration用来配置helloservice
@Configuration
@ConditionalOnMissingBean(HelloService.class)
@EnableConfigurationProperties(HelloProperties.class)
public class HelloServiceAutoConfiguration {
@Bean
public HelloService helloService(){
HelloService helloService = new HelloService();
return helloService;
}
}
最重要的一点,让项目启动时,自动加载指定的自动配置类
在自动配置包中,创建META-INF/spring.factories
因为我们知道启动SpringBoot主程序时,他加载所有spring.factories中的自动配置类,而现在我们自定义的自动配置类还没有在列表中
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.yellowstar.boot.auto.HelloServiceAutoConfiguration
测试
创建一个新的工程
@RestController
public class HelloController {
@Autowired
HelloService helloService;
@GetMapping("/")
public String hello(){
return helloService.sayHello("Tom");
}
}
对属性进行配置
yellowstar:
hello:
prefix: 终于等到你
suffix: 还好我没放弃
结果