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

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

目录


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

1dc618a0ed9580ce8bfa6facb208c08f.png


一、配置文件后缀的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"));
    }


运行结果:


5d4c6812c8535adbb050f4ddf2e1bce8.png

打印了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();
   }

运行结果:

1dc618a0ed9580ce8bfa6facb208c08f.png


三、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();
        }
    }
}


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


1dc618a0ed9580ce8bfa6facb208c08f.png

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


org.springframework.boot.env.EnvironmentPostProcessor=com.springboot.demo3.MyEnvironmentPostProcessor

5d4c6812c8535adbb050f4ddf2e1bce8.png


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


@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();
   }


运行结果显示已经打印:

1dc618a0ed9580ce8bfa6facb208c08f.png


四、指定多个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"));
    }
}


运行:


5d4c6812c8535adbb050f4ddf2e1bce8.png


@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"));
    }
}


运行结果:


46a9d80a6e05e4e3b19d57a0ee70bcdf.png


@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"));
    }
}


运行结果:


1dc618a0ed9580ce8bfa6facb208c08f.png

结果显示,根据编码方式切换了不同的配置文件


那在启动的时候可以切换吗?


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


②参数方式:


在启动参数中配置:


--spring.profiles.active=xx

5d4c6812c8535adbb050f4ddf2e1bce8.png


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

46a9d80a6e05e4e3b19d57a0ee70bcdf.png


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环境下执行,就可这样定义:


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

1dc618a0ed9580ce8bfa6facb208c08f.png

触发了默认和test方法:

5d4c6812c8535adbb050f4ddf2e1bce8.png

指定多个文件:

46a9d80a6e05e4e3b19d57a0ee70bcdf.png

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

66ba272a0bfc97be54a5fa679e3d5482.png

我们也可以在类上指定一个@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 () -> {};
    }
}


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

5d4c6812c8535adbb050f4ddf2e1bce8.png

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

46a9d80a6e05e4e3b19d57a0ee70bcdf.png

再次运行:

66ba272a0bfc97be54a5fa679e3d5482.png

相关文章
|
1月前
|
Java
springboot字段注入@value细节
springboot字段注入@value细节
20 1
|
1月前
|
Java
springboot自动注入避坑
springboot自动注入避坑
20 1
|
16天前
|
Java 应用服务中间件 开发者
Java面试题:解释Spring Boot的优势及其自动配置原理
Java面试题:解释Spring Boot的优势及其自动配置原理
55 0
|
23天前
|
文字识别 Java
文本,文字识别07,SpringBoot服务开发-入参和返回值,编写接口的时候,要注意识别的文字返回的是多行,因此必须是List集合,Bean层,及实体类的搭建
文本,文字识别07,SpringBoot服务开发-入参和返回值,编写接口的时候,要注意识别的文字返回的是多行,因此必须是List集合,Bean层,及实体类的搭建
|
25天前
|
Java 开发者 Spring
深入理解Spring Boot中的自动配置原理
深入理解Spring Boot中的自动配置原理
|
25天前
|
开发框架 Java 开发者
Spring Boot中的自动装配原理
Spring Boot中的自动装配原理
|
1月前
|
消息中间件 Java Maven
深入理解Spring Boot Starter:概念、特点、场景、原理及自定义starter
深入理解Spring Boot Starter:概念、特点、场景、原理及自定义starter
|
18天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的环境保护生活App附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的环境保护生活App附带文章源码部署视频讲解等
20 0
|
19天前
|
Java Spring
深入理解Spring Boot中的Profile配置
深入理解Spring Boot中的Profile配置
|
22天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的营商环境行动计划管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue的营商环境行动计划管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
18 0