diff --git a/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/MBeanExporterParser.java b/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/MBeanExporterParser.java
index c03d788bf3..e41560c10f 100644
--- a/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/MBeanExporterParser.java
+++ b/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/MBeanExporterParser.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2012 the original author or authors.
- *
+ * Copyright 2002-2013 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
- *
+ *
* http://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.
@@ -33,7 +33,7 @@ import org.springframework.util.StringUtils;
/**
* Parser for the 'mbean-export' element of the integration JMX namespace.
- *
+ *
* @author Mark Fisher
* @author Gary Russell
* @since 2.0
@@ -61,7 +61,8 @@ public class MBeanExporterParser extends AbstractSingleBeanDefinitionParser {
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "object-name-static-properties");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "managed-components", "componentNamePatterns");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "shutdown-executor");
-
+ IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "object-naming-strategy", "namingStrategy");
+
builder.addPropertyValue("server", mbeanServer);
this.registerMBeanExporterHelper(parserContext.getRegistry());
}
@@ -70,7 +71,7 @@ public class MBeanExporterParser extends AbstractSingleBeanDefinitionParser {
BeanDefinitionBuilder mBeanExporterHelperBuilder = BeanDefinitionBuilder.rootBeanDefinition(MBeanExporterHelper.class);
BeanDefinitionReaderUtils.registerWithGeneratedName(mBeanExporterHelperBuilder.getBeanDefinition(), registry);
}
-
+
private Object getMBeanServer(Element element, ParserContext parserContext) {
String mbeanServer = element.getAttribute("server");
if (StringUtils.hasText(mbeanServer)) {
diff --git a/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/IntegrationMBeanExporter.java b/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/IntegrationMBeanExporter.java
index 634aeede57..5374236dca 100644
--- a/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/IntegrationMBeanExporter.java
+++ b/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/IntegrationMBeanExporter.java
@@ -167,7 +167,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements BeanPostP
private final MetadataMBeanInfoAssembler assembler = new MetadataMBeanInfoAssembler(attributeSource);
- private final MetadataNamingStrategy namingStrategy = new MetadataNamingStrategy(attributeSource);
+ private final MetadataNamingStrategy defaultNamingStrategy = new MetadataNamingStrategy(attributeSource);
private String[] componentNamePatterns = { "*" };
@@ -183,7 +183,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements BeanPostP
super();
// Shouldn't be necessary, but to be on the safe side...
setAutodetect(false);
- setNamingStrategy(namingStrategy);
+ setNamingStrategy(defaultNamingStrategy);
setAssembler(assembler);
}
@@ -210,7 +210,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements BeanPostP
*/
public void setDefaultDomain(String domain) {
this.domain = domain;
- this.namingStrategy.setDefaultDomain(domain);
+ this.defaultNamingStrategy.setDefaultDomain(domain);
}
public void setComponentNamePatterns(String[] componentNamePatterns) {
diff --git a/spring-integration-jmx/src/main/resources/org/springframework/integration/jmx/config/spring-integration-jmx-3.0.xsd b/spring-integration-jmx/src/main/resources/org/springframework/integration/jmx/config/spring-integration-jmx-3.0.xsd
index 04f8b34b2c..28dc8ecf52 100644
--- a/spring-integration-jmx/src/main/resources/org/springframework/integration/jmx/config/spring-integration-jmx-3.0.xsd
+++ b/spring-integration-jmx/src/main/resources/org/springframework/integration/jmx/config/spring-integration-jmx-3.0.xsd
@@ -204,6 +204,19 @@
+
+
+
+
+
+
+
+
+ An ObjectNamingStrategy to generate the MBean's ObjectName. See the reference documentation
+ for details of the default ObjectName. Also see 'object-name-static-properties'.
+
+
+
diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanExporterParserTests-context.xml b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanExporterParserTests-context.xml
index fc496855ff..3b419513d5 100644
--- a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanExporterParserTests-context.xml
+++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanExporterParserTests-context.xml
@@ -18,11 +18,14 @@
+ object-name-static-properties="appProperties"
+ object-naming-strategy="keyNamer"/>
foo
bar
+
+
diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanExporterParserTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanExporterParserTests.java
index 03c6c870f1..1565113abe 100644
--- a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanExporterParserTests.java
+++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanExporterParserTests.java
@@ -18,6 +18,7 @@ package org.springframework.integration.jmx.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.util.Properties;
@@ -57,6 +58,7 @@ public class MBeanExporterParserTests {
assertTrue(properties.containsKey("foo"));
assertTrue(properties.containsKey("bar"));
assertEquals(server, exporter.getServer());
+ assertSame(context.getBean("keyNamer"), TestUtils.getPropertyValue(exporter, "namingStrategy"));
exporter.destroy();
}
diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanRegistrationCustomNamingTests-context.xml b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanRegistrationCustomNamingTests-context.xml
new file mode 100644
index 0000000000..2e41b34f61
--- /dev/null
+++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanRegistrationCustomNamingTests-context.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanRegistrationCustomNamingTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanRegistrationCustomNamingTests.java
new file mode 100644
index 0000000000..c47cc0363d
--- /dev/null
+++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanRegistrationCustomNamingTests.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2013 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
+ *
+ * http://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.integration.jmx.config;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Set;
+
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jmx.export.naming.KeyNamingStrategy;
+import org.springframework.jmx.export.naming.ObjectNamingStrategy;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * @author Dave Syer
+ * @author Gary Russell
+ * @since 3.0
+ */
+@ContextConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+public class MBeanRegistrationCustomNamingTests {
+
+ @Autowired
+ private MBeanServer server;
+
+ @Test
+ public void testHandlerMBeanRegistration() throws Exception {
+ Set names = server.queryNames(new ObjectName("test.MBeanRegistration:type=Integration,componentType=MessageHandler,*"), null);
+ assertEquals(6, names.size());
+ assertTrue(names.contains(new ObjectName("test.MBeanRegistration:type=Integration,componentType=MessageHandler,name=chain,bean=endpoint")));
+ assertTrue(names.contains(new ObjectName("test.MBeanRegistration:type=Integration,componentType=MessageHandler,name=chain$child.t1,bean=handler")));
+ assertTrue(names.contains(new ObjectName("test.MBeanRegistration:type=Integration,componentType=MessageHandler,name=chain$child.f1,bean=handler")));
+ }
+
+ public static class Source {
+ public String get() {
+ return "foo";
+ }
+ }
+
+ public static class Namer implements ObjectNamingStrategy {
+
+ private final ObjectNamingStrategy realNamer = new KeyNamingStrategy();
+ @Override
+ public ObjectName getObjectName(Object managedBean, String beanKey) throws MalformedObjectNameException {
+ String actualBeanKey = beanKey.replace("type=", "type=Integration,componentType=");
+ return realNamer.getObjectName(managedBean, actualBeanKey);
+ }
+
+ }
+
+}
diff --git a/src/reference/docbook/jmx.xml b/src/reference/docbook/jmx.xml
index 20ef093cc1..d39e8742d8 100644
--- a/src/reference/docbook/jmx.xml
+++ b/src/reference/docbook/jmx.xml
@@ -366,6 +366,46 @@
+
+
+ Custom elements can be appended to the object name by providing a reference to a
+ Properties object in the object-name-static-properties attribute.
+
+
+ Also, since Spring Integration 3.0, you can use a custom
+ ObjectNamingStrategy
+ using the object-naming-strategy attribute. This permits greater control over the naming of the
+ MBeans. For example, to group all Integration MBeans under
+ an 'Integration' type. A simple custom naming strategy implementation might be:
+
+
+
+ The beanKey argument is a String containing the standard object name beginning with
+ the default-domain and including any additional static properties.
+ This example simply moves the standard type part to componentType and
+ sets the type to 'Integration',
+ enabling selection of all Integration MBeans in one query:
+ "my.domain:type=Integration,*. This also groups the beans under one tree entry under the
+ domain in tools like VisualVM.
+
+
+ The default naming strategy is a
+ MetadataNamingStrategy. The exporter propagates the default-domain to that object to allow it
+ to generate a fallback object name if parsing of the bean key fails. If your custom naming strategy is a
+ MetadataNamingStrategy (or subclass), the exporter will not
+ propagate the default-domain; you will need to configure it on your strategy bean.
+
diff --git a/src/reference/docbook/whats-new.xml b/src/reference/docbook/whats-new.xml
index 5cb22379b3..dc68dabc5f 100644
--- a/src/reference/docbook/whats-new.xml
+++ b/src/reference/docbook/whats-new.xml
@@ -63,12 +63,23 @@
JMX Support
- A new <int-jmx:tree-polling-channel-adapter/> is provided; this
- adapter queries the JMX MBean tree and sends a message with a payload that is the
- graph of objects that matches the query. By default the MBeans are mapped to
- primitives and simple Objects like Map, List and arrays - permitting simple
- transformation, for example, to JSON
- .
+
+
+ A new <int-jmx:tree-polling-channel-adapter/> is provided; this
+ adapter queries the JMX MBean tree and sends a message with a payload that is the
+ graph of objects that matches the query. By default the MBeans are mapped to
+ primitives and simple Objects like Map, List and arrays - permitting simple
+ transformation, for example, to JSON.
+
+
+ The IntegrationMBeanExporter now allows the configuration of
+ a custom ObjectNamingStrategy using the naming-strategy
+ attribute.
+
+
+
+
+ For more information, see .