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

相关文章
|
10天前
|
Java 应用服务中间件 测试技术
深入探索Spring Boot Web应用源码及实战应用
【5月更文挑战第11天】本文将详细解析Spring Boot Web应用的源码架构,并通过一个实际案例,展示如何构建一个基于Spring Boot的Web应用。本文旨在帮助读者更好地理解Spring Boot的内部工作机制,以及如何利用这些机制优化自己的Web应用开发。
36 3
|
10天前
|
安全 Java 开发者
深入理解Spring Boot配置绑定及其实战应用
【4月更文挑战第10天】本文详细探讨了Spring Boot中配置绑定的核心概念,并结合实战示例,展示了如何在项目中有效地使用这些技术来管理和绑定配置属性。
20 1
|
1天前
|
Java 应用服务中间件 Maven
SpringBoot概述&SpringBoot基础配置&yml的使用&多环境启动
SpringBoot概述&SpringBoot基础配置&yml的使用&多环境启动
12 2
|
9天前
|
Java 开发者 Spring
springboot @RequiredArgsConstructor @Lazy解决循环依赖的原理
【5月更文挑战第16天】在Spring Boot中,@RequiredArgsConstructor 和 @Lazy 是两个有用的注解,它们分别用于简化构造函数的生成和控制Bean的加载时间。下面详细解析这两个注解的概念、优缺点以及在实际应用中的示例。
28 1
|
9天前
|
Java 开发者 Spring
springboot DDD的概念以及实战
【5月更文挑战第15天】领域驱动设计(Domain-Driven Design,简称DDD)是一种软件设计方法论,它强调基于业务领域的复杂性来构建软件
25 2
|
10天前
|
开发框架 监控 Java
深入探索Spring Boot的监控、管理和测试功能及实战应用
【5月更文挑战第14天】Spring Boot是一个快速开发框架,提供了一系列的功能模块,包括监控、管理和测试等。本文将深入探讨Spring Boot中监控、管理和测试功能的原理与应用,并提供实际应用场景的示例。
19 2
|
10天前
|
XML Java 开发者
springboot 启动原理、启动过程、启动机制的介绍
【5月更文挑战第13天】Spring Boot 是一种基于 Java 的框架,用于创建独立的、生产级别的 Spring 应用程序。它的主要目标是简化 Spring 应用的初始搭建和开发过程,同时提供一系列大型项目常见的非功能性特征(如嵌入式服务器、安全性、度量、健康检查和外部化配置)。
25 3
|
10天前
|
Java Spring 容器
深入理解Spring Boot启动流程及其实战应用
【5月更文挑战第9天】本文详细解析了Spring Boot启动流程的概念和关键步骤,并结合实战示例,展示了如何在实际开发中运用这些知识。
26 2
|
10天前
|
JavaScript Java 开发者
Spring Boot中的@Lazy注解:概念及实战应用
【4月更文挑战第7天】在Spring Framework中,@Lazy注解是一个非常有用的特性,它允许开发者控制Spring容器的bean初始化时机。本文将详细介绍@Lazy注解的概念,并通过一个实际的例子展示如何在Spring Boot应用中使用它。
24 2
|
10天前
|
Java 容器 Spring
【SpringBoot:详解依赖注入和使用配置文件】
【SpringBoot:详解依赖注入和使用配置文件】
16 2