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

相关文章
|
7月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
1138 3
|
5月前
|
监控 Cloud Native Java
Spring Boot 3.x 微服务架构实战指南
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Spring Boot 3.x与微服务架构,探索云原生、性能优化与高可用系统设计。以代码为笔,在二进制星河中谱写极客诗篇。关注我,共赴技术星辰大海!(238字)
1027 2
Spring Boot 3.x 微服务架构实战指南
|
6月前
|
消息中间件 Ubuntu Java
SpringBoot整合MQTT实战:基于EMQX实现双向设备通信
本教程指导在Ubuntu上部署EMQX 5.9.0并集成Spring Boot实现MQTT双向通信,涵盖服务器搭建、客户端配置及生产实践,助您快速构建企业级物联网消息系统。
2337 1
|
5月前
|
JavaScript Java Maven
【SpringBoot(二)】带你认识Yaml配置文件类型、SpringMVC的资源访问路径 和 静态资源配置的原理!
SpringBoot专栏第二章,从本章开始正式进入SpringBoot的WEB阶段开发,本章先带你认识yaml配置文件和资源的路径配置原理,以方便在后面的文章中打下基础
507 4
|
12月前
|
存储 Java 文件存储
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录—— logback.xml 配置文件解析
本文解析了 `logback.xml` 配置文件的详细内容,包括日志输出格式、存储路径、控制台输出及日志级别等关键配置。通过定义 `LOG_PATTERN` 和 `FILE_PATH`,设置日志格式与存储路径;利用 `&lt;appender&gt;` 节点配置控制台和文件输出,支持日志滚动策略(如文件大小限制和保存时长);最后通过 `&lt;logger&gt;` 和 `&lt;root&gt;` 定义日志级别与输出方式。此配置适用于精细化管理日志输出,满足不同场景需求。
2866 1
|
12月前
|
缓存 NoSQL Java
基于SpringBoot的Redis开发实战教程
Redis在Spring Boot中的应用非常广泛,其高性能和灵活性使其成为构建高效分布式系统的理想选择。通过深入理解本文的内容,您可以更好地利用Redis的特性,为应用程序提供高效的缓存和消息处理能力。
1171 79
|
9月前
|
Java API 数据库
JPA简介:Spring Boot环境下的实践指南
上述内容仅是JPA在Spring Boot环境下使用的冰山一角,实际的实践中你会发现更深更广的应用。总而言之,只要掌握了JPA的规则,你就可以借助Spring Boot无比丰富的功能,娴熟地驾驶这台高性能的跑车,在属于你的程序世界里驰骋。
337 15
|
10月前
|
监控 Java 调度
SpringBoot中@Scheduled和Quartz的区别是什么?分布式定时任务框架选型实战
本文对比分析了SpringBoot中的`@Scheduled`与Quartz定时任务框架。`@Scheduled`轻量易用,适合单机简单场景,但存在多实例重复执行、无持久化等缺陷;Quartz功能强大,支持分布式调度、任务持久化、动态调整和失败重试,适用于复杂企业级需求。文章通过特性对比、代码示例及常见问题解答,帮助开发者理解两者差异,合理选择方案。记住口诀:单机简单用注解,多节点上Quartz;若是任务要可靠,持久化配置不能少。
908 4
|
11月前
|
缓存 安全 Java
深入解析HTTP请求方法:Spring Boot实战与最佳实践
这篇博客结合了HTTP规范、Spring Boot实现和实际工程经验,通过代码示例、对比表格和架构图等方式,系统性地讲解了不同HTTP方法的应用场景和最佳实践。
1001 5
|
Java Spring
SpringBoot 实战 不同参数调用不同实现
本文介绍了如何在实际工作中根据不同的入参调用不同的实现,采用`map+enum`的方式实现优雅且严谨的解决方案。通过Spring Boot框架中的工厂模式或策略模式,避免了使用冗长的`if...else...`语句。文中详细展示了定义接口、实现类、枚举类以及控制器调用的代码示例,确保用户输入的合法性并简化了代码逻辑。
498 1
SpringBoot 实战 不同参数调用不同实现

热门文章

最新文章