此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.2.0! |
将 bean 导出到 JMX
Spring 的 JMX 框架中的核心类是MBeanExporter
.这个类是
负责获取您的 Spring bean 并将其注册到 JMX 中MBeanServer
.
例如,请考虑以下类:
-
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
property 告诉MBeanExporter
确切地说,你的 bean 必须是
导出到 JMXMBeanServer
.在默认配置中,每个条目的 key
在beans
Map
用作ObjectName
对于
相应的 entry 值。您可以更改此行为,如控制ObjectName
Bean 的实例.
使用此配置,testBean
bean 在ObjectName
bean:name=testBean1
.默认情况下,所有public
Bean 的属性
作为属性公开,并且所有public
方法(从Object
类)作为作公开。
MBeanExporter 是一个Lifecycle bean (请参阅 Startup and Shutdown Callbacks )。默认情况下,MBean 在
应用程序生命周期。您可以配置phase 在哪个
将发生导出,或者通过设置autoStartup 旗。 |
创建 MBeanServer
上一节中所示的配置假定
应用程序在具有一个(且只有一个)的环境中运行MBeanServer
已经在运行。在这种情况下, Spring 会尝试查找正在运行的MBeanServer
和
向该服务器注册您的 bean(如果有)。当您的
应用程序在容器(例如 Tomcat 或 IBM WebSphere)中运行,该容器具有
有MBeanServer
.
但是,这种方法在独立环境中或在
一个不提供MBeanServer
.要解决此问题,您可以创建一个MBeanServer
实例,方法是添加org.springframework.jmx.support.MBeanServerFactoryBean
类添加到您的配置中。
您还可以确保特定的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
和 is
提供给MBeanExporter
通过server
财产。当您提供自己的MBeanServer
实例中,MBeanExporter
不尝试查找正在运行的MBeanServer
并使用提供的MBeanServer
实例。要使它起作用
正确地,您的 Classpath 上必须有一个 JMX 实现。
重用现有的MBeanServer
如果未指定服务器,则MBeanExporter
尝试自动检测正在运行的MBeanServer
.这在大多数环境中都有效,其中只有一个MBeanServer
instance 为
使用。但是,当存在多个实例时,导出程序可能会选择错误的服务器。
在这种情况下,您应该使用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
即通过 lookup 方法检索,您应该使用 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
也是为 lazy 配置的
初始化时,该MBeanExporter
不违反本合同并避免
实例化 Bean。相反,它会向MBeanServer
并推迟
从容器中获取 Bean,直到对代理进行第一次调用。
这也会影响FactoryBean
分辨率,其中MBeanExporter
会定期
内省生成的对象,有效触发FactoryBean.getObject()
.
为了避免这种情况,请将相应的 bean 定义标记为 lazy-init。
自动注册 MBean
通过MBeanExporter
并且已经是有效的 MBean
按原样注册到MBeanServer
没有 Spring 的进一步干预。
您可以使 MBean 由MBeanExporter
通过设置
这autodetect
property 设置为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 自动检测的 bean
registration 的 bean 名称用作ObjectName
.您可以覆盖此行为,
详见控制ObjectName
Bean 的实例.
控制注册行为
考虑 SpringMBeanExporter
尝试注册MBean
替换为MBeanServer
通过使用ObjectName
bean:name=testBean1
.如果MBean
实例已在同一实例下注册ObjectName
,默认行为
会失败(并抛出一个InstanceAlreadyExistsException
).
您可以精确控制当MBean
是
注册到MBeanServer
.Spring 的 JMX 支持允许三种不同的
注册行为 控制注册时
进程发现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>