文章目录

目录

本篇文章是上篇文章的补充,主要内容概要如下:

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_配置文件

一、配置文件后缀的2种方式

配置文件有2种​​*.properties​​​和​​*.yml​​​,可以单独使用也可以混合使用(不过项目中不知道有没这么干的).
application.properties

jdbc.username=root

application.yml

jdbc:
username: hufanglei
password: 123456

运行入口函数,测试下:

@SpringBootApplication
public class Demo3Application {

public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Demo3Application.class, args);
System.out.println(context.getEnvironment().getProperty("jdbc.username"));
System.out.println(context.getEnvironment().getProperty("jdbc.password"));
}

运行结果:

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_配置文件_02


打印了yml的jdbc.password和properties的username。

结果说明:
1.这2个配置文件都生效了。
2.如果2个配置文件重名,properties的优先级高。都有jdbc.username但是显示的是properties的。

二、配置文件属性注入扩展:集合和数组

配置文件属性可以写数组或集合,现在我们展示用这2种方式接受并读取出来属性值:
​​​application.properties​

ds.hosts[0]=192.168.157.1
ds.hosts[1]=192.168.157.2
ds.hosts[2]=192.168.157.3

#ds.ports=8080,8081,8082 //这种写法也可以
ds.ports[0]=8080
ds.ports[1]=8081
ds.ports[2]=8082
@Component
@ConfigurationProperties("ds")
public class TomcatProperties {
private List<String> hosts = new ArrayList<>();
private String[] ports;
public List<String> getHosts() {
return hosts;
}
public void setHosts(List<String> hosts) {
this.hosts = hosts;
}


public String[] getPorts() {
return ports;
}

public void setPorts(String[] ports) {
this.ports = ports;
}

@Override
public String toString() {
return "TomcatProperties{" +
"hosts=" + hosts +
", ports=" + Arrays.toString(ports) +
'}';
}
}

开始测试:

@SpringBootApplication
public class Demo3Application {

public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Demo3Application.class, args);
System.out.println(context.getBean(TomcatProperties.class));
context.close();
}

运行结果:

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_spring_03

三、EnvironmentPostProcessor 动态加载配置文件

配置文件的属性我们从上篇博客了解到可以使用@Value和Environment的getProperty方法获取, 也可以通过@PropertySource编码方式读取。
其实如果还有一种方式:
可以动态的从不同的地方收集配置文件,加入到自己的项目中并获取。这个就是通过​​​EnvironmentPostProcessor​​​接口。
使用和其他的后置处理器一样,自己实现这个接口,加载就可以。

准备一个配置文件:​​D:/tmp/springboot.properties​

springboot.name=springboot

写自己的环境后置处理器:

@Component
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {

@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
try(InputStream input = new FileInputStream("D:/tmp/springboot.properties")) {
Properties source = new Properties();
source.load(input);
PropertiesPropertySource propertySource = new PropertiesPropertySource("my", source);
environment.getPropertySources().addLast(propertySource);
}catch (Exception e){
e.printStackTrace();
}
}
}

如果想让我们的自定义的后置处理器生效还需要做一步:

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_数组_04


在resource下配置META-INF下配置后置器到spring.factoryries中。

​org.springframework.boot.env.Envirnotallow=com.springboot.demo3.MyEnvironmentPostProcessor​

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_spring boot_05

这样外部的配置文件就注入进来了,我们测试下:

@SpringBootApplication
public class Demo3Application {

public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Demo3Application.class, args);
System.out.println(context.getEnvironment().getProperty("springboot.name"));
context.close();
}

运行结果显示已经打印:

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_spring_06

四、指定多个profile

在开发时可能有多个环境,开发环境dev,测试环境test,默认环境default,生成环境prod,现在我们来切换和指定不同的环境。
准备三个配置文件:
application.properties

jdbc.url=mysql:jdbc;//127.0.0.1/db_springboot

application-dev.properties

jdbc.url=mysql:jdbc;//127.0.0.1/db_springboot_dev

application-test.properties

jdbc.url=mysql:jdbc;//127.0.0.1/db_springboot_test

①硬编码编程方式:

主要是在入口函数中,硬编码指定:

@SpringBootApplication
public class Demo3Application {

public static void main(String[] args) {
//编程的方式指定:生效的profie
SpringApplication app = new SpringApplication(Demo3Application.class);
app.setAdditionalProfiles("dev");
// app.setAdditionalProfiles("test");
ConfigurableApplicationContext context = app.run(args);
System.out.println(context.getEnvironment().getProperty("jdbc.url"));
}
}

运行:

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_数组_07

@SpringBootApplication
public class Demo3Application {

public static void main(String[] args) {
//编程的方式指定:生效的profie
SpringApplication app = new SpringApplication(Demo3Application.class);
// app.setAdditionalProfiles("dev");
app.setAdditionalProfiles("test");
ConfigurableApplicationContext context = app.run(args);
System.out.println(context.getEnvironment().getProperty("jdbc.url"));
}
}

运行结果:

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_数组_08

@SpringBootApplication
public class Demo3Application {

public static void main(String[] args) {
//编程的方式指定:生效的profie
SpringApplication app = new SpringApplication(Demo3Application.class);
// app.setAdditionalProfiles("dev");
// app.setAdditionalProfiles("test");
ConfigurableApplicationContext context = app.run(args);
System.out.println(context.getEnvironment().getProperty("jdbc.url"));
}
}

运行结果:

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_数组_09


​结果显示,根据编码方式切换了不同的配置文件​​ 那在启动的时候可以切换吗?

可以的。可以在启动时候添加参数,指定一个或者多个配置文件。

②参数方式:

在启动参数中配置:

​--spring.profiles.active=xx​

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_配置文件_10


运行结果,显示一切换到test环境下。

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_配置文件_11

bean注入的时候: 方法或者类上添加@Profile

某个类或者某个方法想要在指定的环境下执行,可以通过@Profile注解指定:
我们写个配置类:

@SpringBootConfiguration
public class MyConfig {

@Bean
public Runnable createRunnable(){
System.out.println("========1=====");
return () -> {};
}

@Bean
@Profile("test")
public Runnable createRunnable2(){
System.out.println("========2=====");
return () -> {};
}

@Bean
@Profile("dev")
public Runnable createRunnable3(){
System.out.println("========3=====");
return () -> {};
}
}

我们想要createRunnable方法在默认配置下执行(其实在所有的环境下都会触发),createRunnable2在test环境下执行,createRunnable3在dev环境下执行,就可这样定义:

结合上面的启动参数,我们让其生效:

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_spring boot_12


触发了默认和test方法:

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_数组_13


指定多个文件:

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_配置文件_14


启动后运行结果:都触发了。

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_spring_15


我们也可以在类上指定一个@Profile,虽然没有-prod配置文件,但是我们可以在类上这样写,只有启动参数上加上才可以触发这个类的方法:

@SpringBootConfiguration
@Profile("prod")
public class MyConfig {

@Bean
public Runnable createRunnable(){
System.out.println("========1=====");
return () -> {};
}

@Bean
public Runnable createRunnable2(){
System.out.println("========2=====");
return () -> {};
}

@Bean
public Runnable createRunnable3(){
System.out.println("========3=====");
return () -> {};
}
}

如果启动参数不写,不会打印这几个方法,如下图,空的啥也没打印:

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_数组_16


如果我们这样配置了,就会出触发这个类的所有方法:

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_spring_17


再次运行:

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_spring boot_18


个人微信公号:

搜索: 怒放de每一天

不定时推送相关文章,期待和大家一起成长!!

springboot原理实战(6)--配置文件注入集合,动态注入,切换profile环境_spring_19