结构说明
MyEnvironmentPostProcessor
启动可观察效果
注意:修改时要单独打开target/classes/myEnvironment.properties修改配置,不要使用idea打开修改
1.MyEnvironmentPostProcessor
package com.zsl.springbootlearn.json.environmentPostProcessor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import java.io.IOException;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
/**
* 环境配置参数动态更新 -新建线程调度执行
*
* * */
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor{
private String path;
private final String DEFAULT_LOCATION=ResourceLoader.CLASSPATH_URL_PREFIX;
private final String DEFAULT_NAME="myEnvironment";
private ResourceLoader resourceLoader=new DefaultResourceLoader();
private Properties properties = new Properties();
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
String location=environment.getProperty("myenvironment.location")!=null? environment.getProperty("myenvironment.location"):DEFAULT_LOCATION;
String name=environment.getProperty("myenvironment.name")!=null? environment.getProperty("myenvironment.name"):DEFAULT_NAME;
path=location+name+".properties";
System.out.println(path);
properties=loadProperties(path);
//环境名称随意取,但尽量不能和其他环境名称相同,避免不生效
PropertiesPropertySource propertySource = new PropertiesPropertySource("myEnvironmentPostProcessor", properties);
environment.getPropertySources().addLast(propertySource);
//TODO 新建线程并将properties传给该线程轮询处理该properties
Thread thread=new Thread(new Runnable(){
@Override
public void run() {
while(true){
System.out.println("MyEnvironmentPostProcessorThread线程");
Properties propertiesTemp=loadProperties(path);
System.out.println(" propertiesTemp"+propertiesTemp);
System.out.println(" properties"+properties);
System.out.println(" 配置是否被修改:"+!properties.equals(propertiesTemp));
if(properties!=null && !properties.equals(propertiesTemp)){
Set<String> keys=propertiesTemp.stringPropertyNames();
Iterator<String> iterator=keys.iterator();
while(iterator.hasNext()){
String key=iterator.next();
properties.setProperty(key,propertiesTemp.getProperty(key));
}
}
try {
Thread.sleep(2000); //每2s一次
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread.start();
}
/**
* 从指定的全路径加载配置
* */
private Properties loadProperties(String location){
Properties properties = new Properties();
Resource resource =resourceLoader.getResource(location);
try {
properties.load(resource.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
return properties;
}
}
测试
- @Scope("prototype") 很重要
2.Test
@Component
@Scope("prototype")
public class Test {
@Value("${test.name}")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3.Main
package com.zsl.springbootlearn.json;
import com.zsl.springbootlearn.json.environmentPostProcessor.Test;
import com.zsl.springbootlearn.json.registry.CircuitUtil;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.ApplicationContext;
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class JsonStarter {
public static void main(String[] args) {
ApplicationContext applicationContext=SpringApplication.run(JsonStarter.class,args);
applicationContext.getBean(CircuitUtil.class).call();
while(true){
System.out.println("Main 线程");
System.out.println(" Test.name="+applicationContext.getBean(Test.class).getName());
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
结果:
执行过程中修改配置文件后结果:
改进
可以使用文件监听器进行修改,在文件发生改变时才修改
类似服务端推技术