概述

我们知道,在Spring boot中可以通过xml或者@ImportResource 来引入自己的配置文件,但是这里有个限制,必须是本地,而且格式只能是 properties(或者 yaml)。那么,如果我们有远程配置,如何把他引入进来来呢。

第一种方式

这外一种方法,相对更简单些,但是相对没那么“优雅”。就是通过EnvironmentPostProcessor接口把我们自定义的propertySource加入environment中,

public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
       //这里可以自定义一个MyPropertySource,来保存配置信息
        MyPropertySource propertySource = new MyPropertySource("myPropertySource");
        environment.getPropertySources().addLast(propertySource);
    }
}

同时需要在META-INFO/spring.factories中加入

org.springframework.boot.env.EnvironmentPostProcessor=com.lizo.MyEnvironmentPostProcessor

第二种方式

第二种方式可能相对比较复杂一点,其实是参考Sprng cloud中的做法,其实也只需要3步

第一步,编写PropertySource

编写一个类继承EnumerablePropertySource,然后实现它的抽象方法即可,抽象方法看名字就知道作用,简单起见,这里使用一个map来保存配置,例如:

public class MyPropertySource extends EnumerablePropertySource<Map<String,String>> {

    public MyPropertySource(String name, Map source) {
        super(name, source);
    }

    //获取所有的配置名字
    @Override
    public String[] getPropertyNames() {
        return source.keySet().toArray(new String[source.size()]);
    }

    //根据配置返回对应的属性
    @Override
    public Object getProperty(String name) {
        return source.get(name);
    }
}

第二步,编写PropertySourceLocator

PropertySourceLocator 其实就是用来定位我们前面的PropertySource,需要重写的方法只有一个,就是返回一个PropertySource对象,例如,

public class MyPropertySourceLocator implements PropertySourceLocator {
    @Override
    public PropertySource<?> locate(Environment environment) {
        //简单起见,这里直接创建一个map,你可以在这里写从哪里获取配置信息。无论是本地还是远程
        Map<String,String> properties = new HashMap<>();
        properties.put("myName","lizo");

        MyPropertySource myPropertySource = new MyPropertySource("myPropertySource",properties);
        return myPropertySource;
    }
}

第三步,让PropertySourceLocator生效

新建一个配置类,例如

@Configuration
public class MyConfigBootstrapConfiguration {

    @Bean
    public MyPropertySourceLocator myPropertySourceLocator(){
        return new MyPropertySourceLocator();
    }
}

最后再创建/更新 META-INFO/spring.factories

org.springframework.cloud.bootstrap.BootstrapConfiguration=com.lizo.MyConfigBootstrapConfiguration

简单来说就是给Spring Boot说,这个是一个启动配置类(看名字一种优先级很高的配置类)。

编写测试

测试一

@SpringBootApplication
public class Test2 {

    public static void main(String[] args) throws SQLException {
        ConfigurableApplicationContext run = SpringApplication.run(Test2.class, args);
        Ser bean = run.getBean(Ser.class);
        System.out.println(bean.getMyName());
    }

    @Component
    public static class Ser{
        @Value("${myName}")
        private String myName;

        public String getMyName() {
            return myName;
        }

        public void setMyName(String myName) {
            this.myName = myName;
        }
    }
}

测试二

我们在application配置文件中,引入这个变量呢,例如在application.properties中

my.name=${myName}

同样,结果也是能够生效的

myName就是上面在PropertySourceLocator中写进去的配置属性。运行程序,可以看见确实是可以正确输出。

小结

上面只是抛砖引玉,这样无论是哪里的数据源,都可以通过这种方式编写,把配置交给Spring 管理。这样再也不怕在本地配置文件中出现敏感信息啦,再也不怕修改配置文件需要登录每一个机器修改啦。

01-03 17:50