当前位置:   article > 正文

SpringBoot读取配置文件,命令行指定运行环境,@Profile指定环境装配Bean、拦截器、过滤器,@Condition在满足指定条件时才将某个 bean 加载到应用上下文中@Enable**_指定spring运行环境 命令

指定spring运行环境 命令

application.properties

配置文件默认的文件名字为application.properties,
默认的位置在项目的classpath根目录下,或者classpath:/config目录下,file:/, file:config/

配置文件的名字可以使用--spring.config.name来指定文件的名字,文件扩展名可以省略

配置文件的名字可以使用--spring.config.location来指定文件的位置,配置文件的路径需要指定全路径,包括目录和文件名字,可以指定多个,但要逗号分隔。

配置文件在不同位置时的优先级:

- file:./config/

- file:./

- classpath:/config/

- classpath:/
存在相同配置key时高优先级的配置值会覆盖低优先级的配置值。

springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件

–file:./config/

–file:./

–classpath:/config/

–classpath:/

优先级由高到底,高优先级的配置会覆盖低优先级的配置;

SpringBoot会从这四个位置全部加载主配置文件;互补配置

可以通过spring.config.location来改变默认的配置文件位置,参考这篇

项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互补配置;

使用了外部的配置文件时,又是怎样的呢?

命令行参数
来自java:comp/env的JNDI属性
Java系统属性(System.getProperties() )操作系统环境变量
RandomValuePropertySource配置的random.*属性值
jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件

jar包内部的application-fprofile}.properties或application.yml(带spring.profile)配置文件

jar包外部的application.properties或application.yml(不带spring.profile)配置文件
jar包内部的application.properties或application.yml(不带spring.profile)配置文件Configuration注解类上的PropertySource
通过SpringApplication.setDefaultProperties指定的默认属性

建议整个应用程序坚持使用一种格式。如果您的配置文件在同一位置同时具有.properties.yml格式,.properties则优先。

官方文档

通过配置类进行属性填充

  1. /**
  2. * 支持获取数组,集合
  3. * 配置方式为name[index]=value
  4. */
  5. @Configuration
  6. @Propertysource("classpath:jdbc.properties")
  7. @PropertySource("file:/e:/tmp/jdbc.properties")
  8. //@PropertySources({@Propertysource("classpath:jdbc.properties"),@PropertySource("file:/e:/tmp/jdbc.properties")}) // 或者一次性指定多个
  9. private class PropertiesConfig{
  10. // 你的代码 变量名
  11. @Value(${配置项名称})
  12. private 数据类型 变量名;
  13. }

如何动态获取配置呢?

EnvironmentPostProcessor可以在创建应用程序上下文之前,添加或者修改环境配置

最后一定要在META-INF/spring.factories中添加使之生效。

# Environment Post Processors org.springframework.boot.env.EnvironmentPostProcessor=com.iot.MyEnvironmentPostProcessor 

# com.iot.MyEnvironmentPostProcessor 类MyEnvironmentPostProcessor所在位置的引用path

实现EnvironmentPostProcessor接口,并纳入到Spring容器中

  1. @Component
  2. public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {
  3. public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
  4. try {
  5. InputStream input = new FileInputStream("d:/tmp/springboot. properties");
  6. Properties source = new Properties();
  7. source.load(input);
  8. PropertiesPropertySource propertySource = new PropertiesPropertySource("my ", source);
  9. environment.getPropertySources().addLast(propertySource);
  10. } catch (IOException e) {
  11. e.printStackTrace();
  12. }
  13. }
  14. }

 在 ConfigFileApplicationListener 中调用自定义EnvironmentPostProcessor

Profile

根据环境指定配置文件

通过启动参数来控制生效的profile,可以同时激活多个profile,命令为:

--spring.profiles.active=test,dev

--spring.profiles=test,默认的不激活(不影响其他配置文件)

配置类、Bean可以灵活指定跟随哪个环境,使用@Profile注解

@Profile("dev"),参考Swagger指定环境生效

拦截器、过滤器同理
 

前面阐述了,根据不同的环境加载Bean,接下来,看看根据不同的条件加载Bean......

按条件装配

Condition接口

Spring的注解@Conditional 基于条件的自动配置器,一般配合Condition接口一起使用,只有接口的实现类返回true才装配,否则不装配

它可以用在方法上面,则只对该方法起作用,用在类上面,则对该类的所有方法起作用
 

想在满足指定条件的时候才将某个 bean 加载到应用上下文中,@Conditional注解可以大显身手啦!

  1. @Target({ElementType.TYPE, ElementType.METHOD})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. public @interface Conditional {
  5. Class<? extends Condition>[] value();
  6. }

注解接收的参数是实现了Condition 接口的泛型类,所以,使用 @Conditional 注解,需要实现 Condition 接口。

SpringBoot框架org.springframework.boot.autoconfigure.condition包下已经定义了好了一些注解。在@Conditional的基础上进行了细化,无需出示复杂的介绍信 (实现 Condition 接口),只需要手持预定义好的 @ConditionalOnXxxx 注解

@Enable**注解工作原理

配置文件的属性注入到bean里面去加载到容器的注解 <=== @EnableConfigurationProperties,此注解一般和@ConfigurationProperties一起使用,像这样的还有异步注解,@Async和@EnableAsync等

@Import引入配置

@Import用来导入一个或多个类(会被spring容器托管),或者配置类(配置类里面的bean都会被spring容器托管)

接口ImportSelector的selectImports方法的返回值,必须是class(全称),该class会被spring宫器所托管起来。

ImportBeanDefinitionRegistrar接口的registerBeanDefinitions方法的参数有一个BeanDefinitionRegistry,BeanDefinitionRegistry可以用来往spring容器中注入bean
如此,我们就可以在registerBeanDefinitions方法里面动志的注入bean。

  1. public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
  2. public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, EeanbefinitionRegistry registry) {
  3. BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(User.class);
  4. registry.registerBeanDefinition("user", bdb.getBeanDefinition());
  5. BeanDefinitionBuilder bdb2 = BeanDefinitionBuilder, rootBeanDefinition (Role.class);
  6. registry.registerBeanDefinition("role", bdb2.getBeanDefinition());
  7. BeanDefinitionBuilder bdb3 = BeanDefinitionBuilder.rootBeanDefinition(yconfiguration.class);
  8. registry.registerBeanDefinition(yCconfiguration.class.getName(), bdb3.getBeanDefinition());
  9. }
  10. }


 

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号