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

相关文章
|
17天前
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
|
2月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
734 0
|
2月前
|
前端开发 Java 数据库连接
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
|
3月前
|
Java API 数据库
JPA简介:Spring Boot环境下的实践指南
上述内容仅是JPA在Spring Boot环境下使用的冰山一角,实际的实践中你会发现更深更广的应用。总而言之,只要掌握了JPA的规则,你就可以借助Spring Boot无比丰富的功能,娴熟地驾驶这台高性能的跑车,在属于你的程序世界里驰骋。
158 15
|
6月前
|
Java Spring
SpringBoot自动配置原理
本文深入解析了SpringBoot的核心功能——自动配置,重点探讨了`org.springframework.boot.autoconfigure`及相关注解的工作机制。通过分析`@SpringBootApplication`、`@EnableAutoConfiguration`等注解,揭示了SpringBoot如何基于类路径和条件自动装配Bean
339 9
|
6月前
|
Java
SpringBoot自动装配的原理
在SpringBoot项目的启动引导类上都有一个注解@SpringBootApplication 这个注解是一个复合注解, 其中有三个注解构成 , 分别是 ● @SpringBootConfiguration : 是@Configuration的派生注解 , 标注当前类是一个SpringBoot的配置类 ● @ComponentScan : 开启组件扫描, 默认扫描的是当前启动引导了所在包以及子包 ● @EnableAutoConfiguration : 开启自动配置(自动配置核心注解) 2.在@EnableAutoConfiguration注解的内容使用@Import注解导入了一个AutoC
|
6月前
|
JavaScript 前端开发 Java
Idea启动SpringBoot程序报错:Veb server failed to start. Port 8082 was already in use;端口冲突的原理与解决方案
本文解决了Idea启动SpringBoot程序报错:Veb server failed to start. Port 8082 was already in use的问题,并通过介绍端口的使用原理和操作系统的端口管理机制,可以更有效地解决端口冲突问题,并确保Web服务器能够顺利启动和运行。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
8月前
|
Dart 前端开发 JavaScript
springboot自动配置原理
Spring Boot 自动配置原理:通过 `@EnableAutoConfiguration` 开启自动配置,扫描 `META-INF/spring.factories` 下的配置类,省去手动编写配置文件。使用 `@ConditionalXXX` 注解判断配置类是否生效,导入对应的 starter 后自动配置生效。通过 `@EnableConfigurationProperties` 加载配置属性,默认值与配置文件中的值结合使用。总结来说,Spring Boot 通过这些机制简化了开发配置流程,提升了开发效率。
184 17
springboot自动配置原理
|
5月前
|
安全 前端开发 Java
Spring Boot 项目中触发 Circular View Path 错误的原理与解决方案
在Spring Boot开发中,**Circular View Path**错误常因视图解析与Controller路径重名引发。当视图名称(如`login`)与请求路径相同,Spring MVC无法区分,导致无限循环调用。解决方法包括:1) 明确指定视图路径,避免重名;2) 将视图文件移至子目录;3) 确保Spring Security配置与Controller路径一致。通过合理设定视图和路径,可有效避免该问题,确保系统稳定运行。
362 0
|
7月前
|
Java 数据库 开发者
详细介绍SpringBoot启动流程及配置类解析原理
通过对 Spring Boot 启动流程及配置类解析原理的深入分析,我们可以看到 Spring Boot 在启动时的灵活性和可扩展性。理解这些机制不仅有助于开发者更好地使用 Spring Boot 进行应用开发,还能够在面对问题时,迅速定位和解决问题。希望本文能为您在 Spring Boot 开发过程中提供有效的指导和帮助。
785 12