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

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则优先。

官方文档

通过配置类进行属性填充

/**
* 支持获取数组,集合
* 配置方式为name[index]=value
*/


@Configuration
@Propertysource("classpath:jdbc.properties")
@PropertySource("file:/e:/tmp/jdbc.properties")
//@PropertySources({@Propertysource("classpath:jdbc.properties"),@PropertySource("file:/e:/tmp/jdbc.properties")}) // 或者一次性指定多个
private class PropertiesConfig{
    
    // 你的代码 变量名
    @Value(${配置项名称})
    private 数据类型 变量名;
}

如何动态获取配置呢?

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

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

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

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

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

@Component
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {
    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 (IOException e) {
            e.printStackTrace();
        }
    }
}

 在 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注解可以大显身手啦!

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

注解接收的参数是实现了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。

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, EeanbefinitionRegistry registry) {
        BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(User.class);
        registry.registerBeanDefinition("user", bdb.getBeanDefinition());
        BeanDefinitionBuilder bdb2 = BeanDefinitionBuilder, rootBeanDefinition (Role.class);
        registry.registerBeanDefinition("role", bdb2.getBeanDefinition());
        BeanDefinitionBuilder bdb3 = BeanDefinitionBuilder.rootBeanDefinition(yconfiguration.class);
        registry.registerBeanDefinition(yCconfiguration.class.getName(), bdb3.getBeanDefinition());
    }
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值