引言
application.properties
文件因其静态特性,在应用程序不重启的情况下难以进行配置修改,这限制了系统的灵活性和响应速度。一、代码示例
@Configurationpublic class AppConfig {
@Bean // 声明为多例bean作用域
@Scope("prototype")
public UserService userService(@Value("${pack.app.title:}") String title) {
return new UserService(title) ;
}
}
public class UserService {
private final String title;
public UserService(String title) {
this.title= title;
} // getters, setters}
利用 @Scope 将 UserService 生命为一个多例的作用域,可保证每次 getBean 时 都能拿到的是一个新的对象。每次都会重新注入title值
例如:
@RestController
public class UserController {
@Resource private ApplicationContext context;
@Resource private ApplicationContext context ;
@GetMapping("/update")
public String update() {
// 设置系统属性值;
// 注意你不能吧属性定义在application.yml配置文件中
System.setProperty("pack.app.title", "xxxooo - " + new Random().nextInt(10000)) ;
return "update success" ;
}
@GetMapping("/title")
public String title() {
return this.context.getBean("us", UserService.class).getTitle() ;
}
}
2.使用@RefreshScope
pom.xml文件引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置文件中开启refresh接口
management:
endpoint:
refresh:
enabled: true
endpoints:
web:
exposure:
include: refresh
配置完成后 定义需要实时刷新的bean对象了
@RefreshScope
@Component
public class AppComponent {
@Value("${pack.app.title:}")
private String title ;
public String getTitle() {
return this.title ;
}
}
接下来动态向Environment中添加PropertySource该对象中存入的是我们需要动态刷新的值。
@Service
public class PackPropertyService {
private static final String PACK_PROPERTIES_SOURCE_NAME = "packDynamicProperties" ;
private final ConfigurableEnvironment environment ;
public PackPropertyService(ConfigurableEnvironment environment) {
this.environment = environment ;
}
// 更新或者添加PropertySource操作
public void updateProperty(String key, String value) {
MutablePropertySources propertySources = environment.getPropertySources() ;
if (!propertySources.contains(PACK_PROPERTIES_SOURCE_NAME)) {
Map<String, Object> properties = new HashMap<>() ;
properties.put(key, value) ;
propertySources.addFirst(new MapPropertySource(PACK_PROPERTIES_SOURCE_NAME, properties)) ;
}
else {
// 替换更新值
MapPropertySource propertySource = (MapPropertySource) propertySources.get(PACK_PROPERTIES_SOURCE_NAME) ;
propertySource.getSource().put(key, value) ;
}
}
}
接口测试
@RestController
@RequestMapping("/configprops")
public class PropertyController {
private final PackPropertyService pps ;
private final AppComponent app ;
public PropertyController(PackPropertyService pps, AppComponent app) {
this.pps = pps ; this.app = app ;
}
@PostMapping("/update")
public String updateProperty(String key, String value) {
pps.updateProperty(key, value) ; return "update success" ;
}
@GetMapping("/title")
public String title() {
return app.getTitle() ;
}
}