diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/DefaultEndpointObjectNameFactory.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/DefaultEndpointObjectNameFactory.java index b6b02ea19fe..eac4b9403c9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/DefaultEndpointObjectNameFactory.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/DefaultEndpointObjectNameFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ import javax.management.ObjectName; import org.springframework.boot.actuate.endpoint.jmx.EndpointObjectNameFactory; import org.springframework.boot.actuate.endpoint.jmx.ExposableJmxEndpoint; -import org.springframework.core.env.Environment; +import org.springframework.boot.autoconfigure.jmx.JmxProperties; import org.springframework.jmx.support.ObjectNameManager; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -37,21 +37,18 @@ class DefaultEndpointObjectNameFactory implements EndpointObjectNameFactory { private final JmxEndpointProperties properties; - private final Environment environment; + private final JmxProperties jmxProperties; private final MBeanServer mBeanServer; private final String contextId; - private final boolean uniqueNames; - - DefaultEndpointObjectNameFactory(JmxEndpointProperties properties, Environment environment, MBeanServer mBeanServer, - String contextId) { + DefaultEndpointObjectNameFactory(JmxEndpointProperties properties, JmxProperties jmxProperties, + MBeanServer mBeanServer, String contextId) { this.properties = properties; - this.environment = environment; + this.jmxProperties = jmxProperties; this.mBeanServer = mBeanServer; this.contextId = contextId; - this.uniqueNames = environment.getProperty("spring.jmx.unique-names", Boolean.class, false); } @Override @@ -63,7 +60,7 @@ class DefaultEndpointObjectNameFactory implements EndpointObjectNameFactory { if (this.mBeanServer != null && hasMBean(baseName)) { builder.append(",context=").append(this.contextId); } - if (this.uniqueNames) { + if (this.jmxProperties.isUniqueNames()) { String identity = ObjectUtils.getIdentityHexString(endpoint); builder.append(",identity=").append(identity); } @@ -75,7 +72,10 @@ class DefaultEndpointObjectNameFactory implements EndpointObjectNameFactory { if (StringUtils.hasText(this.properties.getDomain())) { return this.properties.getDomain(); } - return this.environment.getProperty("spring.jmx.default-domain", "org.springframework.boot"); + if (StringUtils.hasText(this.jmxProperties.getDefaultDomain())) { + return this.jmxProperties.getDefaultDomain(); + } + return "org.springframework.boot"; } private boolean hasMBean(String baseObjectName) throws MalformedObjectNameException { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/JmxEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/JmxEndpointAutoConfiguration.java index 9c3ae54857b..d267edee0cf 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/JmxEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/JmxEndpointAutoConfiguration.java @@ -44,10 +44,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; +import org.springframework.boot.autoconfigure.jmx.JmxProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; -import org.springframework.core.env.Environment; import org.springframework.util.ObjectUtils; /** @@ -60,7 +60,7 @@ import org.springframework.util.ObjectUtils; * @since 2.0.0 */ @AutoConfiguration(after = { JmxAutoConfiguration.class, EndpointAutoConfiguration.class }) -@EnableConfigurationProperties(JmxEndpointProperties.class) +@EnableConfigurationProperties({ JmxEndpointProperties.class, JmxProperties.class }) @ConditionalOnProperty(prefix = "spring.jmx", name = "enabled", havingValue = "true") public class JmxEndpointAutoConfiguration { @@ -68,9 +68,13 @@ public class JmxEndpointAutoConfiguration { private final JmxEndpointProperties properties; - public JmxEndpointAutoConfiguration(ApplicationContext applicationContext, JmxEndpointProperties properties) { + private final JmxProperties jmxProperties; + + public JmxEndpointAutoConfiguration(ApplicationContext applicationContext, JmxEndpointProperties properties, + JmxProperties jmxProperties) { this.applicationContext = applicationContext; this.properties = properties; + this.jmxProperties = jmxProperties; } @Bean @@ -85,10 +89,9 @@ public class JmxEndpointAutoConfiguration { @Bean @ConditionalOnMissingBean(EndpointObjectNameFactory.class) - public DefaultEndpointObjectNameFactory endpointObjectNameFactory(MBeanServer mBeanServer, - Environment environment) { + public DefaultEndpointObjectNameFactory endpointObjectNameFactory(MBeanServer mBeanServer) { String contextId = ObjectUtils.getIdentityHexString(this.applicationContext); - return new DefaultEndpointObjectNameFactory(this.properties, environment, mBeanServer, contextId); + return new DefaultEndpointObjectNameFactory(this.properties, this.jmxProperties, mBeanServer, contextId); } @Bean diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/DefaultEndpointObjectNameFactoryTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/DefaultEndpointObjectNameFactoryTests.java index e9f06636195..45c18040580 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/DefaultEndpointObjectNameFactoryTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/DefaultEndpointObjectNameFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.jmx.ExposableJmxEndpoint; -import org.springframework.mock.env.MockEnvironment; +import org.springframework.boot.autoconfigure.jmx.JmxProperties; import org.springframework.util.ObjectUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -40,10 +40,10 @@ import static org.mockito.Mockito.mock; */ class DefaultEndpointObjectNameFactoryTests { - private final MockEnvironment environment = new MockEnvironment(); - private final JmxEndpointProperties properties = new JmxEndpointProperties(); + private final JmxProperties jmxProperties = new JmxProperties(); + private final MBeanServer mBeanServer = mock(MBeanServer.class); private String contextId; @@ -69,7 +69,7 @@ class DefaultEndpointObjectNameFactoryTests { @Test void generateObjectNameWithUniqueNames() { - this.environment.setProperty("spring.jmx.unique-names", "true"); + this.jmxProperties.setUniqueNames(true); assertUniqueObjectName(); } @@ -103,7 +103,7 @@ class DefaultEndpointObjectNameFactoryTests { private ObjectName generateObjectName(ExposableJmxEndpoint endpoint) { try { - return new DefaultEndpointObjectNameFactory(this.properties, this.environment, this.mBeanServer, + return new DefaultEndpointObjectNameFactory(this.properties, this.jmxProperties, this.mBeanServer, this.contextId).getObjectName(endpoint); } catch (MalformedObjectNameException ex) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java index 9456cb35471..fea498382c5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java @@ -35,6 +35,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandi import org.springframework.boot.autoconfigure.condition.SearchStrategy; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; +import org.springframework.boot.autoconfigure.jmx.JmxProperties; import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration; import org.springframework.boot.autoconfigure.sql.init.OnDatabaseInitializationCondition; import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration; @@ -46,7 +47,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.core.env.Environment; import org.springframework.integration.config.EnableIntegration; import org.springframework.integration.config.EnableIntegrationManagement; import org.springframework.integration.config.IntegrationManagementConfigurer; @@ -84,7 +84,7 @@ import org.springframework.util.StringUtils; @AutoConfiguration(after = { DataSourceAutoConfiguration.class, JmxAutoConfiguration.class, TaskSchedulingAutoConfiguration.class }) @ConditionalOnClass(EnableIntegration.class) -@EnableConfigurationProperties(IntegrationProperties.class) +@EnableConfigurationProperties({ IntegrationProperties.class, JmxProperties.class }) public class IntegrationAutoConfiguration { @Bean(name = IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME) @@ -186,14 +186,13 @@ public class IntegrationAutoConfiguration { protected static class IntegrationJmxConfiguration { @Bean - public IntegrationMBeanExporter integrationMbeanExporter(BeanFactory beanFactory, Environment environment) { + public IntegrationMBeanExporter integrationMbeanExporter(BeanFactory beanFactory, JmxProperties properties) { IntegrationMBeanExporter exporter = new IntegrationMBeanExporter(); - String defaultDomain = environment.getProperty("spring.jmx.default-domain"); + String defaultDomain = properties.getDefaultDomain(); if (StringUtils.hasLength(defaultDomain)) { exporter.setDefaultDomain(defaultDomain); } - String serverBean = environment.getProperty("spring.jmx.server", "mbeanServer"); - exporter.setServer(beanFactory.getBean(serverBean, MBeanServer.class)); + exporter.setServer(beanFactory.getBean(properties.getServer(), MBeanServer.class)); return exporter; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfiguration.java index 33f15e5af47..4df5e6570c2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfiguration.java @@ -25,11 +25,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.SearchStrategy; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.EnableMBeanExport; import org.springframework.context.annotation.MBeanExportConfiguration.SpecificPlatform; import org.springframework.context.annotation.Primary; -import org.springframework.core.env.Environment; import org.springframework.jmx.export.MBeanExporter; import org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource; import org.springframework.jmx.export.annotation.AnnotationMBeanExporter; @@ -52,14 +52,15 @@ import org.springframework.util.StringUtils; * @since 1.0.0 */ @AutoConfiguration +@EnableConfigurationProperties(JmxProperties.class) @ConditionalOnClass({ MBeanExporter.class }) @ConditionalOnProperty(prefix = "spring.jmx", name = "enabled", havingValue = "true") public class JmxAutoConfiguration { - private final Environment environment; + private final JmxProperties properties; - public JmxAutoConfiguration(Environment environment) { - this.environment = environment; + public JmxAutoConfiguration(JmxProperties properties) { + this.properties = properties; } @Bean @@ -69,12 +70,11 @@ public class JmxAutoConfiguration { AnnotationMBeanExporter exporter = new AnnotationMBeanExporter(); exporter.setRegistrationPolicy(RegistrationPolicy.FAIL_ON_EXISTING); exporter.setNamingStrategy(namingStrategy); - String serverBean = this.environment.getProperty("spring.jmx.server", "mbeanServer"); + String serverBean = this.properties.getServer(); if (StringUtils.hasLength(serverBean)) { exporter.setServer(beanFactory.getBean(serverBean, MBeanServer.class)); } - boolean uniqueNames = this.environment.getProperty("spring.jmx.unique-names", Boolean.class, false); - exporter.setEnsureUniqueRuntimeObjectNames(uniqueNames); + exporter.setEnsureUniqueRuntimeObjectNames(this.properties.isUniqueNames()); return exporter; } @@ -82,12 +82,11 @@ public class JmxAutoConfiguration { @ConditionalOnMissingBean(value = ObjectNamingStrategy.class, search = SearchStrategy.CURRENT) public ParentAwareNamingStrategy objectNamingStrategy() { ParentAwareNamingStrategy namingStrategy = new ParentAwareNamingStrategy(new AnnotationJmxAttributeSource()); - String defaultDomain = this.environment.getProperty("spring.jmx.default-domain"); + String defaultDomain = this.properties.getDefaultDomain(); if (StringUtils.hasLength(defaultDomain)) { namingStrategy.setDefaultDomain(defaultDomain); } - boolean uniqueNames = this.environment.getProperty("spring.jmx.unique-names", Boolean.class, false); - namingStrategy.setEnsureUniqueRuntimeObjectNames(uniqueNames); + namingStrategy.setEnsureUniqueRuntimeObjectNames(this.properties.isUniqueNames()); return namingStrategy; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jmx/JmxProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jmx/JmxProperties.java new file mode 100644 index 00000000000..70466ee8dd2 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jmx/JmxProperties.java @@ -0,0 +1,82 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jmx; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Configuration properties for JMX. + * + * @author Scott Frederick + * @since 2.7.0 + */ +@ConfigurationProperties(prefix = "spring.jmx") +public class JmxProperties { + + /** + * Expose management beans to the JMX domain. + */ + private boolean enabled = false; + + /** + * Whether unique runtime object names should be ensured. + */ + private boolean uniqueNames = false; + + /** + * MBeanServer bean name. + */ + private String server = "mbeanServer"; + + /** + * JMX domain name. + */ + private String defaultDomain; + + public boolean getEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public boolean isUniqueNames() { + return this.uniqueNames; + } + + public void setUniqueNames(boolean uniqueNames) { + this.uniqueNames = uniqueNames; + } + + public String getServer() { + return this.server; + } + + public void setServer(String server) { + this.server = server; + } + + public String getDefaultDomain() { + return this.defaultDomain; + } + + public void setDefaultDomain(String defaultDomain) { + this.defaultDomain = defaultDomain; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 367b06ba72a..b2cf23b9f78 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -1120,29 +1120,6 @@ "name": "spring.jersey.type", "defaultValue": "servlet" }, - { - "name": "spring.jmx.default-domain", - "type": "java.lang.String", - "description": "JMX domain name." - }, - { - "name": "spring.jmx.enabled", - "type": "java.lang.Boolean", - "description": "Expose management beans to the JMX domain.", - "defaultValue": false - }, - { - "name": "spring.jmx.server", - "type": "java.lang.String", - "description": "MBeanServer bean name.", - "defaultValue": "mbeanServer" - }, - { - "name": "spring.jmx.unique-names", - "type": "java.lang.Boolean", - "description": "Whether unique runtime object names should be ensured.", - "defaultValue": false - }, { "name": "spring.jpa.open-in-view", "defaultValue": true