Browse Source

Adds rebind/refresh an individual bean by type

Fixes gh-1162
pull/1167/head
spencergibb 2 years ago
parent
commit
d1dba70bbf
No known key found for this signature in database
GPG Key ID: 7788A47380690861
  1. 74
      spring-cloud-context/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinder.java
  2. 14
      spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScope.java

74
spring-cloud-context/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinder.java

@ -21,8 +21,10 @@ import java.util.Map; @@ -21,8 +21,10 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
@ -92,31 +94,7 @@ public class ConfigurationPropertiesRebinder @@ -92,31 +94,7 @@ public class ConfigurationPropertiesRebinder
ApplicationContext appContext = this.applicationContext;
while (appContext != null) {
if (appContext.containsLocalBean(name)) {
try {
Object bean = appContext.getBean(name);
if (AopUtils.isAopProxy(bean)) {
bean = ProxyUtils.getTargetObject(bean);
}
if (bean != null) {
// TODO: determine a more general approach to fix this.
// see
// https://github.com/spring-cloud/spring-cloud-commons/issues/571
if (getNeverRefreshable().contains(bean.getClass().getName())) {
return false; // ignore
}
appContext.getAutowireCapableBeanFactory().destroyBean(bean);
appContext.getAutowireCapableBeanFactory().initializeBean(bean, name);
return true;
}
}
catch (RuntimeException e) {
this.errors.put(name, e);
throw e;
}
catch (Exception e) {
this.errors.put(name, e);
throw new IllegalStateException("Cannot rebind to " + name, e);
}
return rebind(name, appContext);
}
else {
appContext = appContext.getParent();
@ -125,6 +103,52 @@ public class ConfigurationPropertiesRebinder @@ -125,6 +103,52 @@ public class ConfigurationPropertiesRebinder
return false;
}
/**
* WARNING: This method rebinds beans from any context in the hierarchy using the main application context.
* @param type bean type to rebind.
* @return true, if successful.
*/
public boolean rebind(Class type) {
String[] beanNamesForType = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.applicationContext, type);
if (beanNamesForType.length > 0) {
String name = beanNamesForType[0];
if (ScopedProxyUtils.isScopedTarget(name)) {
name = ScopedProxyUtils.getOriginalBeanName(name);
}
return rebind(name, this.applicationContext);
}
return false;
}
private boolean rebind(String name, ApplicationContext appContext) {
try {
Object bean = appContext.getBean(name);
if (AopUtils.isAopProxy(bean)) {
bean = ProxyUtils.getTargetObject(bean);
}
if (bean != null) {
// TODO: determine a more general approach to fix this.
// see
// https://github.com/spring-cloud/spring-cloud-commons/issues/571
if (getNeverRefreshable().contains(bean.getClass().getName())) {
return false; // ignore
}
appContext.getAutowireCapableBeanFactory().destroyBean(bean);
appContext.getAutowireCapableBeanFactory().initializeBean(bean, name);
return true;
}
}
catch (RuntimeException e) {
this.errors.put(name, e);
throw e;
}
catch (Exception e) {
this.errors.put(name, e);
throw new IllegalStateException("Cannot rebind to " + name, e);
}
return false;
}
@ManagedAttribute
public Set<String> getNeverRefreshable() {
String neverRefresh = this.applicationContext.getEnvironment()

14
spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScope.java

@ -20,6 +20,7 @@ import java.io.Serializable; @@ -20,6 +20,7 @@ import java.io.Serializable;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.cloud.context.scope.GenericScope;
@ -130,6 +131,19 @@ public class RefreshScope extends GenericScope @@ -130,6 +131,19 @@ public class RefreshScope extends GenericScope
}
}
/**
* WARNING: This method refreshes beans from any context in the hierarchy using the main application context.
* @param type bean type to rebind.
* @return true, if successful.
*/
public boolean refresh(Class type) {
String[] beanNamesForType = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.context, type);
if (beanNamesForType.length > 0) {
return refresh(beanNamesForType[0]);
}
return false;
}
@ManagedOperation(description = "Dispose of the current instance of bean name "
+ "provided and force a refresh on next method execution.")
public boolean refresh(String name) {

Loading…
Cancel
Save