Spring 的 JMX 框架中的核心类是 .这个类是
负责获取您的 Spring bean 并将其注册到 JMX 中。
例如,请考虑以下类:MBeanExporterMBeanServer
package org.springframework.jmx;
public class JmxTestBean implements IJmxTestBean {
	private String name;
	private int age;
	private boolean isSuperman;
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public int add(int x, int y) {
		return x + y;
	}
	public void dontExposeMe() {
		throw new RuntimeException();
	}
}
要将此 Bean 的属性和方法公开为
MBean 中,您可以在
配置文件并传入 Bean,如下例所示:MBeanExporter
<beans>
	<!-- this bean must not be lazily initialized if the exporting is to happen -->
	<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
		<property name="beans">
			<map>
				<entry key="bean:name=testBean1" value-ref="testBean"/>
			</map>
		</property>
	</bean>
	<bean id="testBean" class="org.springframework.jmx.JmxTestBean">
		<property name="name" value="TEST"/>
		<property name="age" value="100"/>
	</bean>
</beans>
前面配置代码段中的相关 Bean 定义是 Bean。该属性准确地告诉您的 bean 必须是哪个
导出到 JMX 。在默认配置中,每个条目的 key
在 中用作 bean 引用的
相应的 entry 值。您可以更改此行为,如控制 Bean 的 ObjectName 实例中所述。exporterbeansMBeanExporterMBeanServerbeansMapObjectName
使用此配置,Bean 在 .默认情况下,Bean 的所有属性
作为属性公开,所有方法(从类继承的方法除外)都作为操作公开。testBeanObjectNamebean:name=testBean1publicpublicObject
MBeanExporter是 bean (请参阅 Startup and Shutdown Callbacks )。默认情况下,MBean 在
应用程序生命周期。您可以配置在
发生导出或通过设置标志来禁用自动注册。LifecyclephaseautoStartup | 
MBeanExporter是 bean (请参阅 Startup and Shutdown Callbacks )。默认情况下,MBean 在
应用程序生命周期。您可以配置在
发生导出或通过设置标志来禁用自动注册。LifecyclephaseautoStartup | 
创建 MBeanServer
上一节中所示的配置假定
应用程序在已运行一个 (且只有一个) 的环境中运行。在这种情况下, Spring 会尝试找到正在运行的
向该服务器注册您的 bean(如果有)。当您的
应用程序在容器(例如 Tomcat 或 IBM WebSphere)中运行,该容器具有
有。MBeanServerMBeanServerMBeanServer
但是,这种方法在独立环境中或在
不提供 .要解决此问题,您可以通过将类的实例添加到您的配置中来以声明方式创建实例。
您还可以通过将实例属性的值设置为返回的值 an 来确保使用 specific,如下例所示:MBeanServerMBeanServerorg.springframework.jmx.support.MBeanServerFactoryBeanMBeanServerMBeanExporterserverMBeanServerMBeanServerFactoryBean
<beans>
	<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"/>
	<!--
	this bean needs to be eagerly pre-instantiated in order for the exporting to occur;
	this means that it must not be marked as lazily initialized
	-->
	<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
		<property name="beans">
			<map>
				<entry key="bean:name=testBean1" value-ref="testBean"/>
			</map>
		</property>
		<property name="server" ref="mbeanServer"/>
	</bean>
	<bean id="testBean" class="org.springframework.jmx.JmxTestBean">
		<property name="name" value="TEST"/>
		<property name="age" value="100"/>
	</bean>
</beans>
在前面的示例中,由 和 创建的实例
通过物业供应给。当您提供自己的实例时,它不会尝试查找正在运行的实例,而是使用提供的实例。要使它起作用
正确地,您的 Classpath 上必须有一个 JMX 实现。MBeanServerMBeanServerFactoryBeanMBeanExporterserverMBeanServerMBeanExporterMBeanServerMBeanServer
重用现有的MBeanServer
如果未指定服务器,则 会尝试自动检测正在运行的 .这在大多数环境中都有效,其中只有一个实例
使用。但是,当存在多个实例时,导出程序可能会选择错误的服务器。
在这种情况下,您应该使用 来指示要
,如下例所示:MBeanExporterMBeanServerMBeanServerMBeanServeragentId
<beans>
	<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
		<!-- indicate to first look for a server -->
		<property name="locateExistingServerIfPossible" value="true"/>
		<!-- search for the MBeanServer instance with the given agentId -->
		<property name="agentId" value="MBeanServer_instance_agentId>"/>
	</bean>
	<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
		<property name="server" ref="mbeanServer"/>
		...
	</bean>
</beans>
对于现有具有通过查找方法检索的动态(或未知)的平台或情况,您应该使用 factory-method,
如下例所示:MBeanServeragentId
<beans>
	<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
		<property name="server">
			<!-- Custom MBeanServerLocator -->
			<bean class="platform.package.MBeanServerLocator" factory-method="locateMBeanServer"/>
		</property>
	</bean>
	<!-- other beans here -->
</beans>
延迟初始化的 MBean
如果将 Bean 配置为 Lazy
初始化时,它不会破坏此 Contract 并避免
实例化 Bean。相反,它使用 and defers 注册一个代理
从容器中获取 Bean,直到对代理进行第一次调用。MBeanExporterMBeanExporterMBeanServer
这也会影响 Will 经常的分辨率
内省生成的对象,有效地触发 .
为了避免这种情况,请将相应的 bean 定义标记为 lazy-init。FactoryBeanMBeanExporterFactoryBean.getObject()
自动注册 MBean
通过 导出并且已经是有效 MBean 的任何 bean
按原样注册,无需 Spring 的进一步干预。
您可以使 MBean 由 by 设置
属性设置为 ,如下例所示:MBeanExporterMBeanServerMBeanExporterautodetecttrue
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
	<property name="autodetect" value="true"/>
</bean>
<bean name="spring:mbean=true" class="org.springframework.jmx.export.TestDynamicMBean"/>
在前面的示例中,调用的 Bean 已经是有效的 JMX MBean
并由 Spring 自动注册。默认情况下,为 JMX 自动检测的 bean
registration 的 bean 名称用作 .您可以覆盖此行为,
如控制 Bean 的 ObjectName 实例中所述。spring:mbean=trueObjectName
控制注册行为
考虑 Spring 尝试使用 .如果已在 same 下注册实例,则默认行为
是失败的(并抛出一个 )。MBeanExporterMBeanMBeanServerObjectNamebean:name=testBean1MBeanObjectNameInstanceAlreadyExistsException
您可以精确控制
已注册 .Spring 的 JMX 支持允许三种不同的
注册行为 控制注册时
进程发现 已在同一 下注册 。
下表总结了这些注册行为:MBeanMBeanServerMBeanObjectName
| 注册行为 | 解释 | 
|---|---|
  | 
这是默认的注册行为。如果实例已经
 在同一 项下注册的 ,正在注册的 不是
 registered,并引发 an。现有不受影响。  | 
  | 
如果已在同一 下注册实例,则不会注册正在注册的实例。现有的是
 unaffected,并且 no 被抛出。这在
 多个应用程序希望在共享的 .  | 
  | 
如果实例已在同一 、
 existing 的 existing 将取消注册,并且 new 将在其位置上注册(new 实际上替换了
 previous 实例)。  | 
上表中的值定义为类的枚举。
如果要更改默认注册行为,则需要将定义上的属性值设置为以下值之一
值。RegistrationPolicyregistrationPolicyMBeanExporter
以下示例显示如何从默认注册进行更改
behavior 更改为 behavior:REPLACE_EXISTING
<beans>
	<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
		<property name="beans">
			<map>
				<entry key="bean:name=testBean1" value-ref="testBean"/>
			</map>
		</property>
		<property name="registrationPolicy" value="REPLACE_EXISTING"/>
	</bean>
	<bean id="testBean" class="org.springframework.jmx.JmxTestBean">
		<property name="name" value="TEST"/>
		<property name="age" value="100"/>
	</bean>
</beans>
| 注册行为 | 解释 | 
|---|---|
  | 
这是默认的注册行为。如果实例已经
 在同一 项下注册的 ,正在注册的 不是
 registered,并引发 an。现有不受影响。  | 
  | 
如果已在同一 下注册实例,则不会注册正在注册的实例。现有的是
 unaffected,并且 no 被抛出。这在
 多个应用程序希望在共享的 .  | 
  | 
如果实例已在同一 、
 existing 的 existing 将取消注册,并且 new 将在其位置上注册(new 实际上替换了
 previous 实例)。  |