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.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.BeanFactoryAware;
|
import org.springframework.beans.factory.BeanFactoryAware;
|
||||||
import org.springframework.beans.factory.ListableBeanFactory;
|
import org.springframework.beans.factory.ListableBeanFactory;
|
||||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
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.ApplicationListener;
|
||||||
import org.springframework.context.SmartLifecycle;
|
import org.springframework.context.SmartLifecycle;
|
||||||
import org.springframework.jmx.export.MBeanExportException;
|
import org.springframework.jmx.export.MBeanExportException;
|
||||||
|
@ -52,7 +55,7 @@ import org.springframework.util.ObjectUtils;
|
||||||
* @author Christian Dupuis
|
* @author Christian Dupuis
|
||||||
*/
|
*/
|
||||||
public class EndpointMBeanExporter extends MBeanExporter implements SmartLifecycle,
|
public class EndpointMBeanExporter extends MBeanExporter implements SmartLifecycle,
|
||||||
BeanFactoryAware {
|
BeanFactoryAware, ApplicationContextAware {
|
||||||
|
|
||||||
public static final String DEFAULT_DOMAIN = "org.springframework.boot";
|
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 final ReentrantLock lifecycleLock = new ReentrantLock();
|
||||||
|
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
private ListableBeanFactory beanFactory;
|
private ListableBeanFactory beanFactory;
|
||||||
|
|
||||||
private String domain = DEFAULT_DOMAIN;
|
private String domain = DEFAULT_DOMAIN;
|
||||||
|
@ -91,6 +96,12 @@ public class EndpointMBeanExporter extends MBeanExporter implements SmartLifecyc
|
||||||
setAssembler(this.assembler);
|
setAssembler(this.assembler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext)
|
||||||
|
throws BeansException {
|
||||||
|
this.applicationContext = applicationContext;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBeanFactory(BeanFactory beanFactory) {
|
public void setBeanFactory(BeanFactory beanFactory) {
|
||||||
super.setBeanFactory(beanFactory);
|
super.setBeanFactory(beanFactory);
|
||||||
|
@ -159,6 +170,10 @@ public class EndpointMBeanExporter extends MBeanExporter implements SmartLifecyc
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append(this.domain);
|
builder.append(this.domain);
|
||||||
builder.append(":type=Endpoint");
|
builder.append(":type=Endpoint");
|
||||||
|
if (parentContextContainsSameBean(this.applicationContext, beanKey)) {
|
||||||
|
builder.append(",context="
|
||||||
|
+ ObjectUtils.getIdentityHexString(this.applicationContext));
|
||||||
|
}
|
||||||
builder.append(",name=" + beanKey);
|
builder.append(",name=" + beanKey);
|
||||||
if (this.ensureUniqueRuntimeObjectNames) {
|
if (this.ensureUniqueRuntimeObjectNames) {
|
||||||
builder.append(",identity="
|
builder.append(",identity="
|
||||||
|
@ -172,6 +187,21 @@ public class EndpointMBeanExporter extends MBeanExporter implements SmartLifecyc
|
||||||
return this.defaultNamingStrategy.getObjectName(bean, beanKey);
|
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() {
|
private String getStaticNames() {
|
||||||
if (this.objectNameStaticProperties.isEmpty()) {
|
if (this.objectNameStaticProperties.isEmpty()) {
|
||||||
return "";
|
return "";
|
||||||
|
@ -243,4 +273,5 @@ public class EndpointMBeanExporter extends MBeanExporter implements SmartLifecyc
|
||||||
this.lifecycleLock.unlock();
|
this.lifecycleLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,11 +97,45 @@ public class EndpointMBeanExportAutoConfigurationTests {
|
||||||
+ ",key1=value1,key2=value2")));
|
+ ",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,
|
private ObjectName getObjectName(String domain, String beanKey,
|
||||||
ApplicationContext applicationContext) throws MalformedObjectNameException {
|
ApplicationContext applicationContext) throws MalformedObjectNameException {
|
||||||
return ObjectNameManager.getInstance(String.format(
|
if (applicationContext.getParent() != null) {
|
||||||
"%s:type=Endpoint,name=%s,identity=%s", domain, beanKey,
|
return ObjectNameManager
|
||||||
ObjectUtils.getIdentityHexString(applicationContext.getBean(beanKey))));
|
.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
|
@Configuration
|
||||||
|
|
Loading…
Reference in New Issue