Initialize beans after rebinding as necessary
On startup a bean will be bound by the ConfigurationPropertiesBindingPostProcessor and then initialized by the ApplicationContext. The ConfigurationPropertiesRebinder does the binding but not the initialization (until this change). Fixes gh-80
This commit is contained in:
@@ -25,12 +25,14 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.context.properties.ConfigurationBeanFactoryMetaData;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
|
||||
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.jmx.export.annotation.ManagedAttribute;
|
||||
import org.springframework.jmx.export.annotation.ManagedOperation;
|
||||
import org.springframework.jmx.export.annotation.ManagedResource;
|
||||
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
@@ -39,7 +41,8 @@ import org.springframework.stereotype.Component;
|
||||
*/
|
||||
@Component
|
||||
@ManagedResource
|
||||
public class ConfigurationPropertiesRebinder implements BeanPostProcessor, ApplicationListener<EnvironmentChangeEvent> {
|
||||
public class ConfigurationPropertiesRebinder implements BeanPostProcessor,
|
||||
ApplicationListener<EnvironmentChangeEvent>, ApplicationContextAware {
|
||||
|
||||
private ConfigurationBeanFactoryMetaData metaData;
|
||||
|
||||
@@ -52,6 +55,14 @@ public class ConfigurationPropertiesRebinder implements BeanPostProcessor, Appli
|
||||
|
||||
private Map<String, Object> beans = new HashMap<String, Object>();
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param beans the bean meta data to set
|
||||
*/
|
||||
@@ -93,13 +104,17 @@ public class ConfigurationPropertiesRebinder implements BeanPostProcessor, Appli
|
||||
@ManagedOperation
|
||||
public void rebind(String name) {
|
||||
binder.postProcessBeforeInitialization(beans.get(name), name);
|
||||
if (applicationContext != null) {
|
||||
applicationContext.getAutowireCapableBeanFactory().initializeBean(
|
||||
beans.get(name), name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ManagedAttribute
|
||||
public Set<String> getBeanNames() {
|
||||
return new HashSet<String>(beans.keySet());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(EnvironmentChangeEvent event) {
|
||||
rebind();
|
||||
|
||||
@@ -17,6 +17,8 @@ package org.springframework.cloud.context.properties;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -55,17 +57,20 @@ public class ConfigurationPropertiesRebinderIntegrationTests {
|
||||
EnvironmentTestUtils.addEnvironment(environment, "message:Foo");
|
||||
// ...but don't refresh, so the bean stays the same:
|
||||
assertEquals("Hello scope!", properties.getMessage());
|
||||
assertEquals(1, properties.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
public void testRefresh() throws Exception {
|
||||
assertEquals(1, properties.getCount());
|
||||
assertEquals("Hello scope!", properties.getMessage());
|
||||
// Change the dynamic property source...
|
||||
EnvironmentTestUtils.addEnvironment(environment, "message:Foo");
|
||||
// ...and then refresh, so the bean is re-initialized:
|
||||
rebinder.rebind();
|
||||
assertEquals("Foo", properties.getMessage());
|
||||
assertEquals(2, properties.getCount());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -84,6 +89,10 @@ public class ConfigurationPropertiesRebinderIntegrationTests {
|
||||
protected static class TestProperties {
|
||||
private String message;
|
||||
private int delay;
|
||||
private int count = 0;
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
@@ -96,6 +105,10 @@ public class ConfigurationPropertiesRebinderIntegrationTests {
|
||||
public void setDelay(int delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.count ++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user