Align expectations of various JMX configurations
They all want to create an MBeanServer and when that happens user sees no MBeans, or sometimes just one set (Spring Core, Spring Integration or Spring Boot). To harmonise them we create a @Bean of type MBeanServer and link to it in the other autoconfigs Fixes gh-1046
This commit is contained in:
parent
6f98c63ac0
commit
09200361de
|
@ -16,12 +16,15 @@
|
||||||
|
|
||||||
package org.springframework.boot.actuate.autoconfigure;
|
package org.springframework.boot.actuate.autoconfigure;
|
||||||
|
|
||||||
|
import javax.management.MBeanServer;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter;
|
import org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||||
|
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
@ -35,7 +38,7 @@ import org.springframework.util.StringUtils;
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnExpression("${endpoints.jmx.enabled:true} && ${spring.jmx.enabled:true}")
|
@ConditionalOnExpression("${endpoints.jmx.enabled:true} && ${spring.jmx.enabled:true}")
|
||||||
@AutoConfigureAfter({ EndpointAutoConfiguration.class })
|
@AutoConfigureAfter({ EndpointAutoConfiguration.class, JmxAutoConfiguration.class })
|
||||||
@EnableConfigurationProperties(EndpointMBeanExportProperties.class)
|
@EnableConfigurationProperties(EndpointMBeanExportProperties.class)
|
||||||
public class EndpointMBeanExportAutoConfiguration {
|
public class EndpointMBeanExportAutoConfiguration {
|
||||||
|
|
||||||
|
@ -43,13 +46,14 @@ public class EndpointMBeanExportAutoConfiguration {
|
||||||
EndpointMBeanExportProperties properties = new EndpointMBeanExportProperties();
|
EndpointMBeanExportProperties properties = new EndpointMBeanExportProperties();
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public EndpointMBeanExporter endpointMBeanExporter() {
|
public EndpointMBeanExporter endpointMBeanExporter(MBeanServer server) {
|
||||||
EndpointMBeanExporter mbeanExporter = new EndpointMBeanExporter();
|
EndpointMBeanExporter mbeanExporter = new EndpointMBeanExporter();
|
||||||
|
|
||||||
String domain = this.properties.getDomain();
|
String domain = this.properties.getDomain();
|
||||||
if (StringUtils.hasText(domain)) {
|
if (StringUtils.hasText(domain)) {
|
||||||
mbeanExporter.setDomain(domain);
|
mbeanExporter.setDomain(domain);
|
||||||
}
|
}
|
||||||
|
mbeanExporter.setServer(server);
|
||||||
|
|
||||||
mbeanExporter.setEnsureUniqueRuntimeObjectNames(this.properties.isUniqueNames());
|
mbeanExporter.setEnsureUniqueRuntimeObjectNames(this.properties.isUniqueNames());
|
||||||
mbeanExporter.setObjectNameStaticProperties(this.properties.getStaticNames());
|
mbeanExporter.setObjectNameStaticProperties(this.properties.getStaticNames());
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.junit.After;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
import org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter;
|
import org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter;
|
||||||
|
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
@ -56,7 +57,8 @@ public class EndpointMBeanExportAutoConfigurationTests {
|
||||||
@Test
|
@Test
|
||||||
public void testEndpointMBeanExporterIsInstalled() {
|
public void testEndpointMBeanExporterIsInstalled() {
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
this.context = new AnnotationConfigApplicationContext();
|
||||||
this.context.register(TestConfiguration.class, EndpointAutoConfiguration.class,
|
this.context.register(TestConfiguration.class, JmxAutoConfiguration.class,
|
||||||
|
EndpointAutoConfiguration.class,
|
||||||
EndpointMBeanExportAutoConfiguration.class);
|
EndpointMBeanExportAutoConfiguration.class);
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
assertNotNull(this.context.getBean(EndpointMBeanExporter.class));
|
assertNotNull(this.context.getBean(EndpointMBeanExporter.class));
|
||||||
|
@ -68,7 +70,8 @@ public class EndpointMBeanExportAutoConfigurationTests {
|
||||||
environment.setProperty("endpoints.jmx.enabled", "false");
|
environment.setProperty("endpoints.jmx.enabled", "false");
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
this.context = new AnnotationConfigApplicationContext();
|
||||||
this.context.setEnvironment(environment);
|
this.context.setEnvironment(environment);
|
||||||
this.context.register(EndpointAutoConfiguration.class,
|
this.context.register(JmxAutoConfiguration.class,
|
||||||
|
EndpointAutoConfiguration.class,
|
||||||
EndpointMBeanExportAutoConfiguration.class);
|
EndpointMBeanExportAutoConfiguration.class);
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
this.context.getBean(EndpointMBeanExporter.class);
|
this.context.getBean(EndpointMBeanExporter.class);
|
||||||
|
@ -84,7 +87,8 @@ public class EndpointMBeanExportAutoConfigurationTests {
|
||||||
environment.setProperty("endpoints.jmx.static_names", "key1=value1, key2=value2");
|
environment.setProperty("endpoints.jmx.static_names", "key1=value1, key2=value2");
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
this.context = new AnnotationConfigApplicationContext();
|
||||||
this.context.setEnvironment(environment);
|
this.context.setEnvironment(environment);
|
||||||
this.context.register(EndpointAutoConfiguration.class,
|
this.context.register(JmxAutoConfiguration.class,
|
||||||
|
EndpointAutoConfiguration.class,
|
||||||
EndpointMBeanExportAutoConfiguration.class);
|
EndpointMBeanExportAutoConfiguration.class);
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
this.context.getBean(EndpointMBeanExporter.class);
|
this.context.getBean(EndpointMBeanExporter.class);
|
||||||
|
@ -101,11 +105,12 @@ public class EndpointMBeanExportAutoConfigurationTests {
|
||||||
public void testEndpointMBeanExporterInParentChild() throws IntrospectionException,
|
public void testEndpointMBeanExporterInParentChild() throws IntrospectionException,
|
||||||
InstanceNotFoundException, MalformedObjectNameException, ReflectionException {
|
InstanceNotFoundException, MalformedObjectNameException, ReflectionException {
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
this.context = new AnnotationConfigApplicationContext();
|
||||||
this.context.register(EndpointAutoConfiguration.class,
|
this.context.register(JmxAutoConfiguration.class,
|
||||||
|
EndpointAutoConfiguration.class,
|
||||||
EndpointMBeanExportAutoConfiguration.class);
|
EndpointMBeanExportAutoConfiguration.class);
|
||||||
|
|
||||||
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
|
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
|
||||||
parent.register(EndpointAutoConfiguration.class,
|
parent.register(JmxAutoConfiguration.class, EndpointAutoConfiguration.class,
|
||||||
EndpointMBeanExportAutoConfiguration.class);
|
EndpointMBeanExportAutoConfiguration.class);
|
||||||
this.context.setParent(parent);
|
this.context.setParent(parent);
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,11 @@
|
||||||
<artifactId>spring-integration-core</artifactId>
|
<artifactId>spring-integration-core</artifactId>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.integration</groupId>
|
||||||
|
<artifactId>spring-integration-jmx</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-jms</artifactId>
|
<artifactId>spring-jms</artifactId>
|
||||||
|
|
|
@ -16,19 +16,27 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.integration;
|
package org.springframework.boot.autoconfigure.integration;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.integration.config.EnableIntegration;
|
import org.springframework.integration.config.EnableIntegration;
|
||||||
|
import org.springframework.integration.jmx.config.EnableIntegrationMBeanExport;
|
||||||
|
import org.springframework.integration.jmx.config.IntegrationMBeanExportConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||||
* Auto-configuration} for Spring Integration.
|
* Auto-configuration} for Spring Integration.
|
||||||
*
|
*
|
||||||
* @author Artem Bilan
|
* @author Artem Bilan
|
||||||
|
* @author Dave Syer
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnClass(EnableIntegration.class)
|
@ConditionalOnClass(EnableIntegration.class)
|
||||||
|
@AutoConfigureAfter(JmxAutoConfiguration.class)
|
||||||
public class IntegrationAutoConfiguration {
|
public class IntegrationAutoConfiguration {
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@ -36,4 +44,12 @@ public class IntegrationAutoConfiguration {
|
||||||
protected static class IntegrationConfiguration {
|
protected static class IntegrationConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnClass(EnableIntegrationMBeanExport.class)
|
||||||
|
@ConditionalOnMissingBean(IntegrationMBeanExportConfiguration.class)
|
||||||
|
@ConditionalOnExpression("${spring.jmx.enabled:true}")
|
||||||
|
@EnableIntegrationMBeanExport(defaultDomain = "${spring.jmx.default_domain:}", server = "${spring.jmx.server:mbeanServer}")
|
||||||
|
protected static class IntegrationJmxConfiguration {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,17 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.jmx;
|
package org.springframework.boot.autoconfigure.jmx;
|
||||||
|
|
||||||
|
import javax.management.MBeanServer;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.EnableMBeanExport;
|
import org.springframework.context.annotation.EnableMBeanExport;
|
||||||
import org.springframework.jmx.export.MBeanExporter;
|
import org.springframework.jmx.export.MBeanExporter;
|
||||||
|
import org.springframework.jmx.support.MBeanServerFactoryBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link EnableAutoConfiguration Auto-configuration} to enable/disable Spring's
|
* {@link EnableAutoConfiguration Auto-configuration} to enable/disable Spring's
|
||||||
|
@ -34,14 +38,21 @@ import org.springframework.jmx.export.MBeanExporter;
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnClass({ MBeanExporter.class })
|
@ConditionalOnClass({ MBeanExporter.class })
|
||||||
@ConditionalOnMissingBean({ MBeanExporter.class })
|
|
||||||
@ConditionalOnExpression("${spring.jmx.enabled:true}")
|
@ConditionalOnExpression("${spring.jmx.enabled:true}")
|
||||||
public class JmxAutoConfiguration {
|
public class JmxAutoConfiguration {
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableMBeanExport(defaultDomain = "${spring.jmx.default_domain:}", server = "${spring.jmx.server:}")
|
@ConditionalOnMissingBean({ MBeanExporter.class })
|
||||||
|
@EnableMBeanExport(defaultDomain = "${spring.jmx.default_domain:}", server = "${spring.jmx.server:mbeanServer}")
|
||||||
public static class MBeanExport {
|
public static class MBeanExport {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(MBeanServer.class)
|
||||||
|
public MBeanServerFactoryBean mbeanServer() {
|
||||||
|
MBeanServerFactoryBean factory = new MBeanServerFactoryBean();
|
||||||
|
factory.setLocateExistingServerIfPossible(true);
|
||||||
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package org.springframework.boot.autoconfigure.integration;
|
package org.springframework.boot.autoconfigure.integration;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.integration.support.channel.HeaderChannelRegistry;
|
import org.springframework.integration.support.channel.HeaderChannelRegistry;
|
||||||
|
|
||||||
|
@ -32,7 +33,8 @@ public class IntegrationAutoConfigurationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void integrationIsAvailable() {
|
public void integrationIsAvailable() {
|
||||||
this.context.register(IntegrationAutoConfiguration.class);
|
this.context.register(JmxAutoConfiguration.class,
|
||||||
|
IntegrationAutoConfiguration.class);
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
assertNotNull(this.context.getBean(HeaderChannelRegistry.class));
|
assertNotNull(this.context.getBean(HeaderChannelRegistry.class));
|
||||||
this.context.close();
|
this.context.close();
|
||||||
|
|
|
@ -1688,6 +1688,17 @@ infrastructure to receive messages asynchronously. Spring AMQP provides a simila
|
||||||
feature set for the ``Advanced Message Queuing Protocol'' and Boot also provides
|
feature set for the ``Advanced Message Queuing Protocol'' and Boot also provides
|
||||||
auto-configuration options for `RabbitTemplate` and RabbitMQ.
|
auto-configuration options for `RabbitTemplate` and RabbitMQ.
|
||||||
|
|
||||||
|
[[boot-features-messaging]]
|
||||||
|
== Spring Integration
|
||||||
|
|
||||||
|
Spring Integration provides abstractions over messaging and also other
|
||||||
|
transports such as HTTP, TCP etc. If Spring Integration is available
|
||||||
|
on your classpath it will be initialized through the `@EnableIntegration`
|
||||||
|
annotation. Message processing statistics will be published over JMX if
|
||||||
|
``spring-integration-jmx'' is also on the classpath.
|
||||||
|
See the {sc-spring-boot-autoconfigure}/integration/IntegrationAutoConfiguration.{sc-ext}[`IntegrationAutoConfiguration`]
|
||||||
|
class for more details.
|
||||||
|
|
||||||
[[boot-features-jms]]
|
[[boot-features-jms]]
|
||||||
== JMS
|
== JMS
|
||||||
|
|
||||||
|
@ -1792,6 +1803,17 @@ into your own beans:
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
|
[[boot-features-jmx]]
|
||||||
|
== Monitoring and management over JMX
|
||||||
|
|
||||||
|
Java Management Extensions (JMX) provide a standard mechanism to
|
||||||
|
monitor and manage applications. By default Spring Boot will create an
|
||||||
|
`MBeanServer` with bean id "mbeanServer" and expose any of your beans
|
||||||
|
that are annotated with Spring JMX annotations (`@ManagedResource`,
|
||||||
|
`@ManagedAttribute`, `@ManagedOperation`).
|
||||||
|
|
||||||
|
See the {sc-spring-boot-autoconfigure}/jmx/JmxAutoConfiguration.{sc-ext}[`JmxAutoConfiguration`]
|
||||||
|
class for more details.
|
||||||
|
|
||||||
[[boot-features-testing]]
|
[[boot-features-testing]]
|
||||||
== Testing
|
== Testing
|
||||||
|
|
|
@ -23,6 +23,10 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-integration</artifactId>
|
<artifactId>spring-boot-starter-integration</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.integration</groupId>
|
||||||
|
<artifactId>spring-integration-jmx</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
logging.file: /tmp/logs/app.log
|
logging.file: /tmp/logs/app.log
|
||||||
service.greeting: Hello
|
service.greeting: Hello
|
||||||
|
debug: true
|
Loading…
Reference in New Issue