自 JDK 5.0 引入註解後,Spring 提供了一套 JMX 註解 (org.springframework.jmx.export.annotation.*) 配合 AnnotationJmxAttributeSource、MetadataMBeanInfoAssembler、MetadataNamingStrategy,讓開發者無需 XML 配置即可將任意 POJO 導出為 JMX MBean,極大簡化了管理監控接口的開發。
| 註解 | 目標 | 用途 |
|---|---|---|
@ManagedResource | 類 | 標記為 JMX 管理資源,配置 objectName、描述、持久化策略等 |
@ManagedAttribute | 方法 (getter/setter) | 暴露為 MBean 屬性,可設描述、默認值、貨幣時間限制等 |
@ManagedOperation | 方法 | 暴露為 MBean 操作 |
@ManagedOperationParameters / @ManagedOperationParameter | 方法 | 描述操作參數名稱與說明 |
import org.springframework.jmx.export.annotation.*;
@ManagedResource(
objectName = "bean:name=testJmxBean",
description = "My Managed Bean",
log = true, logFile = "jmx.log",
currencyTimeLimit = 15, persistPolicy = "OnUpdate",
persistPeriod = 200, persistLocation = "foo", persistName = "bar"
)
public class AnnotationTestBean {
private String name;
private int age;
private List<String> values;
@ManagedAttribute(description = "The Age Attribute", currencyTimeLimit = 1)
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@ManagedAttribute(description = "The Values Attribute", currencyTimeLimit = 1)
public List<String> getValues() {
values = new ArrayList<>(2);
values.add("hello"); values.add("world");
return values;
}
@ManagedAttribute(description = "The Name Attribute", currencyTimeLimit = 20,
defaultValue = "bar", persistPolicy = "OnUpdate")
public void setName(String name) {
this.name = name;
System.out.println("set: " + name);
}
@ManagedAttribute(defaultValue = "foo", persistPeriod = 300)
public String getName() {
System.out.println("get: " + name);
return name;
}
@ManagedOperation(description = "Add two numbers")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "x", description = "The first number"),
@ManagedOperationParameter(name = "y", description = "The second number")
})
public int add(int x, int y) { return x + y; }
public void dontExposeMe() { throw new RuntimeException(); } // 不會被暴露
}
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:context="https://www.springframework.org/schema/context"
xsi:schemaLocation="https://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-2.0.xsd
https://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context-2.0.xsd">
<!-- 核心導出器 -->
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="assembler" ref="assembler" />
<property name="namingStrategy" ref="namingStrategy" />
<property name="autodetect" value="true" /> <!-- 自動檢測 @ManagedResource -->
</bean>
<!-- 註解屬性源 -->
<bean id="jmxAttributeSource"
class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
<!-- 元數據組裝器:讀取註解構建 MBeanInfo -->
<bean id="assembler"
class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
<property name="attributeSource" ref="jmxAttributeSource" />
</bean>
<!-- 命名策略:從 @ManagedResource.objectName 獲取 ObjectName -->
<bean id="namingStrategy"
class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
<property name="attributeSource" ref="jmxAttributeSource" />
</bean>
<!-- 目標 Bean -->
<bean id="testBean" class="AnnotationTestBean">
<property name="name" value="TEST" />
<property name="age" value="100" />
</bean>
</beans>
public class Main {
public static void main(String[] args) throws InterruptedException {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
context.start();
// JVM 啟動參數需加上: -Dcom.sun.management.jmxremote
while (true) { Thread.sleep(10000); }
}
}
啟動後打開 JConsole 連接進程,即可在 MBean 標籤頁看到 bean:name=testJmxBean,操作屬性與方法。
| 參數 | 適用註解 | 說明 |
|---|---|---|
| objectName | @ManagedResource | MBean 的 ObjectName,唯一標識 |
| description | 所有 | 友好描述,顯示於 JConsole |
| currencyTimeLimit | @ManagedResource, @ManagedAttribute | 描述符字段,控制緩存有效期 |
| defaultValue | @ManagedAttribute | 屬性默認值 |
| log / logFile | @ManagedResource | 啟用日誌記錄與文件路徑 |
| persistPolicy / persistPeriod / persistLocation / persistName | @ManagedResource | 持久化策略配置 |
| name / index | @ManagedOperationParameter | 參數顯示名與索引 |
本文內容主要整理自 Spring 官方參考文檔,更多高級用法 (如通知、動態 MBean) 請參閱 Spring Reference。