Append context id to objectName of Endpoint MBeans if name already exists in MBeanServer
This commit is contained in:
parent
9758ca5535
commit
5cf2387e58
|
@ -28,11 +28,14 @@ import javax.management.ObjectName;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.jmx.export.MBeanExportException;
|
||||
|
@ -52,7 +55,7 @@ import org.springframework.util.ObjectUtils;
|
|||
* @author Christian Dupuis
|
||||
*/
|
||||
public class EndpointMBeanExporter extends MBeanExporter implements SmartLifecycle,
|
||||
BeanFactoryAware {
|
||||
BeanFactoryAware, ApplicationContextAware {
|
||||
|
||||
public static final String DEFAULT_DOMAIN = "org.springframework.boot";
|
||||
|
||||
|
@ -76,6 +79,8 @@ public class EndpointMBeanExporter extends MBeanExporter implements SmartLifecyc
|
|||
|
||||
private final ReentrantLock lifecycleLock = new ReentrantLock();
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private ListableBeanFactory beanFactory;
|
||||
|
||||
private String domain = DEFAULT_DOMAIN;
|
||||
|
@ -91,6 +96,12 @@ public class EndpointMBeanExporter extends MBeanExporter implements SmartLifecyc
|
|||
setAssembler(this.assembler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
super.setBeanFactory(beanFactory);
|
||||
|
@ -159,6 +170,10 @@ public class EndpointMBeanExporter extends MBeanExporter implements SmartLifecyc
|
|||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(this.domain);
|
||||
builder.append(":type=Endpoint");
|
||||
if (parentContextContainsSameBean(this.applicationContext, beanKey)) {
|
||||
builder.append(",context="
|
||||
+ ObjectUtils.getIdentityHexString(this.applicationContext));
|
||||
}
|
||||
builder.append(",name=" + beanKey);
|
||||
if (this.ensureUniqueRuntimeObjectNames) {
|
||||
builder.append(",identity="
|
||||
|
@ -172,6 +187,21 @@ public class EndpointMBeanExporter extends MBeanExporter implements SmartLifecyc
|
|||
return this.defaultNamingStrategy.getObjectName(bean, beanKey);
|
||||
}
|
||||
|
||||
private boolean parentContextContainsSameBean(ApplicationContext applicationContext,
|
||||
String beanKey) {
|
||||
if (applicationContext.getParent() != null) {
|
||||
try {
|
||||
this.applicationContext.getParent().getBean(beanKey, Endpoint.class);
|
||||
return true;
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
return parentContextContainsSameBean(applicationContext.getParent(),
|
||||
beanKey);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getStaticNames() {
|
||||
if (this.objectNameStaticProperties.isEmpty()) {
|
||||
return "";
|
||||
|
@ -243,4 +273,5 @@ public class EndpointMBeanExporter extends MBeanExporter implements SmartLifecyc
|
|||
this.lifecycleLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -97,11 +97,45 @@ public class EndpointMBeanExportAutoConfigurationTests {
|
|||
+ ",key1=value1,key2=value2")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEndpointMBeanExporterInParentChild() throws IntrospectionException,
|
||||
InstanceNotFoundException, MalformedObjectNameException, ReflectionException {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
this.context.register(EndpointAutoConfiguration.class,
|
||||
EndpointMBeanExportAutoConfiguration.class);
|
||||
|
||||
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
|
||||
parent.register(EndpointAutoConfiguration.class,
|
||||
EndpointMBeanExportAutoConfiguration.class);
|
||||
this.context.setParent(parent);
|
||||
|
||||
parent.refresh();
|
||||
this.context.refresh();
|
||||
|
||||
parent.close();
|
||||
|
||||
System.out.println("parent " + ObjectUtils.getIdentityHexString(parent));
|
||||
System.out.println("child " + ObjectUtils.getIdentityHexString(this.context));
|
||||
}
|
||||
|
||||
private ObjectName getObjectName(String domain, String beanKey,
|
||||
ApplicationContext applicationContext) throws MalformedObjectNameException {
|
||||
return ObjectNameManager.getInstance(String.format(
|
||||
"%s:type=Endpoint,name=%s,identity=%s", domain, beanKey,
|
||||
ObjectUtils.getIdentityHexString(applicationContext.getBean(beanKey))));
|
||||
if (applicationContext.getParent() != null) {
|
||||
return ObjectNameManager
|
||||
.getInstance(String.format(
|
||||
"%s:type=Endpoint,name=%s,context=%s,identity=%s", domain,
|
||||
beanKey,
|
||||
ObjectUtils.getIdentityHexString(applicationContext),
|
||||
ObjectUtils.getIdentityHexString(applicationContext
|
||||
.getBean(beanKey))));
|
||||
}
|
||||
else {
|
||||
return ObjectNameManager
|
||||
.getInstance(String.format("%s:type=Endpoint,name=%s,identity=%s",
|
||||
domain, beanKey, ObjectUtils
|
||||
.getIdentityHexString(applicationContext
|
||||
.getBean(beanKey))));
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
|
Loading…
Reference in New Issue