此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10! |
将 Bean 导出到 JMX
Spring 的 JMX 框架中的核心类是MBeanExporter
. 这个类是负责获取您的 Spring Bean 并将它们注册到 JMXMBeanServer
. 例如,考虑以下类:
-
Java
-
Kotlin
public class JmxTestBean implements IJmxTestBean {
private String name;
private int age;
@Override
public int getAge() {
return age;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public int add(int x, int y) {
return x + y;
}
@Override
public void dontExposeMe() {
throw new RuntimeException();
}
}
class JmxTestBean : IJmxTestBean {
private lateinit var name: String
private var age = 0
override fun getAge(): Int {
return age
}
override fun setAge(age: Int) {
this.age = age
}
override fun setName(name: String) {
this.name = name
}
override fun getName(): String {
return name
}
override fun add(x: Int, y: Int): Int {
return x + y
}
override fun dontExposeMe() {
throw RuntimeException()
}
}
要将此 Bean 的属性和方法公开为MBean,您可以配置MBeanExporter
类在你的配置文件中并传入 bean,如以下示例所示:
-
Java
-
Kotlin
-
Xml
@Configuration
public class JmxConfiguration {
@Bean
MBeanExporter exporter(JmxTestBean testBean) {
MBeanExporter exporter = new MBeanExporter();
exporter.setBeans(Map.of("bean:name=testBean1", testBean));
return exporter;
}
@Bean
JmxTestBean testBean() {
JmxTestBean testBean = new JmxTestBean();
testBean.setName("TEST");
testBean.setAge(100);
return testBean;
}
}
@Configuration
class JmxConfiguration {
@Bean
fun exporter(testBean: JmxTestBean) = MBeanExporter().apply {
setBeans(mapOf("bean:name=testBean1" to testBean))
}
@Bean
fun testBean() = JmxTestBean().apply {
name = "TEST"
age = 100
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- this bean must not be lazily initialized if the exporting is to happen -->
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="bean:name=testBean1" value-ref="testBean"/>
</map>
</property>
</bean>
<bean id="testBean" class="org.example.JmxTestBean">
<property name="name" value="TEST"/>
<property name="age" value="100"/>
</bean>
</beans>
前面配置代码段中的相关 bean 定义是exporter
豆。 这beans
属性告诉MBeanExporter
确切地说,您的哪些 bean 必须导出到 JMXMBeanServer
. 在默认配置中,每个条目的键 在beans
Map
用作ObjectName
对于相应的条目值。您可以更改此行为,如控制ObjectName
Bean 的实例.
使用此配置,testBean
bean 在ObjectName
bean:name=testBean1
. 默认情况下,所有public
bean 的属性作为属性公开,并且所有public
方法(除了那些继承自Object
类)作为作公开。
MBeanExporter 是一个Lifecycle bean(请参阅启动和关闭回调)。默认情况下,MBean 在应用程序生命周期期间尽可能晚地导出应用程序生命周期。您可以配置phase 其中导出发生或通过设置autoStartup 旗。 |
创建 MBeanServer
上一节中显示的配置假定应用程序在具有一个(并且只有一个)的环境中运行MBeanServer
已经运行。在这种情况下,Spring 会尝试找到正在运行的MBeanServer
和 向该服务器(如果有)注册您的 bean。当您的应用程序在容器(例如 Tomcat 或 IBM WebSphere)中运行时,此行为很有用,该容器具有其 有MBeanServer
.
但是,这种方法在独立环境中或在一个不提供MBeanServer
. 要解决此问题,您可以创建一个MBeanServer
实例,通过添加org.springframework.jmx.support.MBeanServerFactoryBean
class 添加到您的配置中。您还可以确保特定的MBeanServer
通过设置MBeanExporter
实例的server
属性设置为MBeanServer
返回的值MBeanServerFactoryBean
,如以下示例所示:
<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>
在前面的示例中,实例MBeanServer
由MBeanServerFactoryBean
并且是提供给MBeanExporter
通过server
财产。 当您提供自己的MBeanServer
实例,MBeanExporter
不尝试定位正在运行的MBeanServer
并使用提供的MBeanServer
实例。 要使其正常工作正确地,您必须在类路径上有一个 JMX 实现。
重用现有的MBeanServer
如果未指定服务器,则MBeanExporter
尝试自动检测正在运行的MBeanServer
. 这适用于大多数环境中,其中只有一个MBeanServer
实例是 使用。 但是,当存在多个实例时,导出器可能会选择错误的服务器。在这种情况下,您应该使用MBeanServer
agentId
以指示要使用的实例,如以下示例所示:
<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>
对于现有的MBeanServer
具有动态(或未知)agentId
通过查找方法检索的,您应该使用 factory-method,如以下示例所示:
<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 配置为MBeanExporter
也配置为惰性初始化,则MBeanExporter
不会破坏此合约并避免实例化 bean。相反,它向MBeanServer
并推迟从容器中获取 Bean,直到对代理进行第一次调用。
这也会影响FactoryBean
resolution,其中MBeanExporter
会定期对产生的对象进行内省,有效触发FactoryBean.getObject()
. 为了避免这种情况,请将相应的 bean 定义标记为 lazy-init。
自动注册 MBean
通过MBeanExporter
并且已经是有效的 MBean按原样注册在MBeanServer
无需 Spring 的进一步干预。您可以使 MBean 被MBeanExporter
通过设置 这autodetect
属性设置为true
,如以下示例所示:
<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"/>
在前面的示例中,调用spring:mbean=true
已经是一个有效的 JMX MBean并由 Spring 自动注册。默认情况下,自动检测到 JMX 的 beanregistration 的 bean 名称用作ObjectName
. 您可以覆盖此行为,详见控制ObjectName
Bean 的实例.
控制注册行为
考虑以下场景: 弹簧MBeanExporter
尝试注册MBean
使用MBeanServer
通过使用ObjectName
bean:name=testBean1
. 如果MBean
实例已在同一个ObjectName
,默认行为是失败(并抛出InstanceAlreadyExistsException
).
您可以精确控制当MBean
是 注册MBeanServer
. Spring 的 JMX 支持允许三种不同的registration 行为来控制注册行为,当注册进程发现MBean
已在同一ObjectName
. 下表总结了这些注册行为:
注册行为 | 解释 |
---|---|
|
这是默认注册行为。如果 |
|
如果 |
|
如果 |
上表中的值定义为RegistrationPolicy
类。
如果要更改默认注册行为,需要将registrationPolicy
您的财产MBeanExporter
定义到其中之一
值。
以下示例演示如何从默认注册更改
行为设置为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>