Spring: how to make transparent configuration of executable file properties

Spring has a nice PropertyPlaceholderConfigurer mechanism for entering values ​​such as timeouts, JDBC addresses, etc. in Spring beans to configure the target. Is there any reasonable way to handle configuration values ​​that may change at runtime?

UPDATE: when using Spring 3.1, there is a good way to enable non-static configuration sources, such as a database, through a PropertySource . Some ApplicationContexts provide an update mechanism that is basically capable of handling changing configuration values. However, it first stops the application, then creates all the beans fresh, and then starts the application context again. However, for our purposes, I need a way to do this transparently so that the server correctly processes current requests.

Another idea to do this is a custom scope that creates new objects when the configuration changes. Unfortunately, the ObjectFactory provided by Scope uses the preliminary definition of a bean, so placeholders are not re-read from the configuration. Thus, the created objects have the same configuration .: - (

+6
source share
4 answers

The following is a bit strange, but it works. You create a custom scope called reconfigurable that discards all the beans created in that scope whenever a configuration update occurs. Thus, after changing the configuration, a new bean will be created.

Actual configuration values ​​must be obtained using the spring expression language, since the values ​​for both the $ {} syntax and the PropertyOverrideConfigurer property appear to be constantly committed to BeanDefinition. A bean declaration for a bean with an override property of someProperty as follows:

 <bean class="blablu.Testbean" scope="reconfigurable" p:someProperty="#{ config['configexplicit']}"> <aop:scoped-proxy /> </bean> 

You need to use aop: scoped-proxy so that the beans that use this bean always retrieve the latest configured bean from the custom scope.

Declaring properties using @Value also works; if you use component scanning, you need to declare the area using annotation

 @Scope(value="reconfigurableScope", proxyMode=ScopedProxyMode.TARGET_CLASS) 

If you need details: the main idea of ​​the area:

 public class ReconfigurableScope implements Scope { private final Map<String, Object> nameToObjectMap = new ConcurrentHashMap<String, Object>(); public Object get(final String name, final ObjectFactory<?> objectFactory) { Object bean = nameToObjectMap.get(name); if (null == bean) { bean = objectFactory.getObject(); nameToObjectMap.put(name, bean); } return bean; } // called from outside on each configuration change public void update(final ConfigurationObservable observable, final Object arg) { nameToObjectMap.clear(); } } 

In addition, some security and thread cleaning tools: remote beans need to be destroyed a little later and close the application context.

+2
source

Unfortunately, the configuration from the properties files is static and occurs at startup. What I usually do is expose dynamic attributes with :

 @ManagedResource @Service public class BusinessService { @ManagedAttribute private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void businessMethod() { //use age... } } 

Do not forget to add:

 <context:mbean-export/> 

To your configuration. Now you can access and change this attribute through jconsole or any other JMX client. See Also: 23.3.2 Using Source-Level Metadata (JDK 5.0 Annotations) .

+2
source

There is an example of what you are trying to do here: https://github.com/ldojo/spring-cloud-config-examples

It demonstrates how Spring cloud server and client service can communicate through the Spring cloud bus, and client configuration properties can change at runtime when the configuration changes in the Config Server repository.

+1
source

For efficient reconfiguration at runtime, you can use the spring Cloud Config project. In this layout, you will have a Configuration Repository , say a git repository that contains your configuration values. Then put the Configuration Server in front of this repository. This server will be updated whenever there is a break in the backup storage. Finally, your applications will be clients of this Config Server and they will pull new configs from it. Check out Spring Cloud for more details.

0
source

Source: https://habr.com/ru/post/912218/


All Articles