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月前
|
XML Java 开发者
Spring Boot开箱即用可插拔实现过程演练与原理剖析
【11月更文挑战第20天】Spring Boot是一个基于Spring框架的项目,其设计目的是简化Spring应用的初始搭建以及开发过程。Spring Boot通过提供约定优于配置的理念,减少了大量的XML配置和手动设置,使得开发者能够更专注于业务逻辑的实现。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,为开发者提供一个全面的理解。
36 0
|
1天前
|
Java 数据库连接 Maven
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
自动装配是现在面试中常考的一道面试题。本文基于最新的 SpringBoot 3.3.3 版本的源码来分析自动装配的原理,并在文未说明了SpringBoot2和SpringBoot3的自动装配源码中区别,以及面试回答的拿分核心话术。
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
|
8天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
52 14
|
1月前
|
Java Spring
SpringBoot自动装配的原理
在Spring Boot项目中,启动引导类通常使用`@SpringBootApplication`注解。该注解集成了`@SpringBootConfiguration`、`@ComponentScan`和`@EnableAutoConfiguration`三个注解,分别用于标记配置类、开启组件扫描和启用自动配置。
59 17
|
1月前
|
Java 容器
springboot自动配置原理
启动类@SpringbootApplication注解下,有三个关键注解 (1)@springbootConfiguration:表示启动类是一个自动配置类 (2)@CompontScan:扫描启动类所在包外的组件到容器中 (3)@EnableConfigutarion:最关键的一个注解,他拥有两个子注解,其中@AutoConfigurationpackageu会将启动类所在包下的所有组件到容器中,@Import会导入一个自动配置文件选择器,他会去加载META_INF目录下的spring.factories文件,这个文件中存放很大自动配置类的全类名,这些类会根据元注解的装配条件生效,生效
|
1月前
|
Java 数据库连接 数据库
springboot启动配置文件-bootstrap.yml常用基本配置
以上是一些常用的基本配置项,在实际应用中可能会根据需求有所变化。通过合理配置 `bootstrap.yml`文件,可以确保应用程序在启动阶段加载正确的配置,并顺利启动运行。
175 2
|
1月前
|
Java Spring 容器
SpringBoot读取配置文件的6种方式,包括:通过Environment、@PropertySource、@ConfigurationProperties、@Value读取配置信息
SpringBoot读取配置文件的6种方式,包括:通过Environment、@PropertySource、@ConfigurationProperties、@Value读取配置信息
122 3
|
2月前
|
自然语言处理 Java API
Spring Boot 接入大模型实战:通义千问赋能智能应用快速构建
【10月更文挑战第23天】在人工智能(AI)技术飞速发展的今天,大模型如通义千问(阿里云推出的生成式对话引擎)等已成为推动智能应用创新的重要力量。然而,对于许多开发者而言,如何高效、便捷地接入这些大模型并构建出功能丰富的智能应用仍是一个挑战。
264 6
|
2月前
|
Java Spring 容器
springboot @RequiredArgsConstructor @Lazy解决循环依赖的原理
【10月更文挑战第15天】在Spring Boot应用中,循环依赖是一个常见问题,当两个或多个Bean相互依赖时,会导致Spring容器陷入死循环。本文通过比较@RequiredArgsConstructor和@Lazy注解,探讨它们解决循环依赖的原理和优缺点。@RequiredArgsConstructor通过构造函数注入依赖,使代码更简洁;@Lazy则通过延迟Bean的初始化,打破创建顺序依赖。两者各有优势,需根据具体场景选择合适的方法。
116 4
|
2月前
|
Java 测试技术 开发者
springboot学习四:Spring Boot profile多环境配置、devtools热部署
这篇文章主要介绍了如何在Spring Boot中进行多环境配置以及如何整合DevTools实现热部署,以提高开发效率。
104 2