使用 Spring 的JMX annotation 让POJO对象输出到JMX
自JDK5.0 引入注解(Annotation)后,让Java的开发简化了很多,让开发者几乎摆脱复杂的
配置文件的烦恼。本文将介绍Spring提供的一套相当于Commons Attribut属性类的注解和一个策略接口 JmxAttributeSource 的实现类 AnnotationsJmxAttributeSource, 这个类允许 MBeanInfoAssembler 来读这些注解。本文就给大家展示一下,使用Spring的JMX annotation,如何简单快速让POJO对象输出到JMX.
里面的出现的类名的功能,在下面介绍,先来看一个例子:
先编写一个POJO对象
1
import
java.util.ArrayList;
2 import java.util.List;
3
4 import org.springframework.jmx.export.annotation.ManagedAttribute;
5 import org.springframework.jmx.export.annotation.ManagedOperation;
6 import org.springframework.jmx.export.annotation.ManagedOperationParameter;
7 import org.springframework.jmx.export.annotation.ManagedOperationParameters;
8 import org.springframework.jmx.export.annotation.ManagedResource;
9
10 // 实例标记为由JMX管理的资源
11 @ManagedResource(objectName = " bean:name=testJmxBean " , description = " My Managed Bean " , log = true ,
12 logFile = " jmx.log " , currencyTimeLimit = 15 , persistPolicy = " OnUpdate " , persistPeriod = 200 ,
13 persistLocation = " foo " , persistName = " bar " )
14 public class AnnotationTestBean {
15
16 private String name;
17 private int age;
18
19 private List < String > values;
20
21 // 把getter或setter标记为JMX的属性
22 @ManagedAttribute(description = " The Age Attribute " , currencyTimeLimit = 1 )
23 public int getAge() {
24 return age;
25 }
26
27 public void setAge( int age) {
28 this .age = age;
29 }
30
31 @ManagedAttribute(description = " The values Attribute " , currencyTimeLimit = 1 )
32 public List < String > getValues() {
33 values = new ArrayList < String > ( 2 );
34 values.add( " hello " );
35 values.add( " world " );
36 return values;
37 }
38
39 @ManagedAttribute(description = " The Name Attribute " ,
40 currencyTimeLimit = 20 ,
41 defaultValue = " bar " ,
42 persistPolicy = " OnUpdate " )
43 public void setName(String name) {
44 this .name = name;
45 System.out.println( " set: " + name);
46 }
47
48 @ManagedAttribute(defaultValue = " foo " , persistPeriod = 300 )
49 public String getName() {
50 System.out.println( " get: " + name);
51 return name;
52 }
53
54 // 把方法标记为JMX的操作
55 @ManagedOperation(description = " Add two numbers " )
56 @ManagedOperationParameters({
57 @ManagedOperationParameter(name = " x " , description = " The first number " ),
58 @ManagedOperationParameter(name = " y " , description = " The second number " )})
59 public int add( int x, int y) {
60 return x + y;
61 }
62
63 public void dontExposeMe() {
64 throw new RuntimeException();
65 }
66 }
67
2 import java.util.List;
3
4 import org.springframework.jmx.export.annotation.ManagedAttribute;
5 import org.springframework.jmx.export.annotation.ManagedOperation;
6 import org.springframework.jmx.export.annotation.ManagedOperationParameter;
7 import org.springframework.jmx.export.annotation.ManagedOperationParameters;
8 import org.springframework.jmx.export.annotation.ManagedResource;
9
10 // 实例标记为由JMX管理的资源
11 @ManagedResource(objectName = " bean:name=testJmxBean " , description = " My Managed Bean " , log = true ,
12 logFile = " jmx.log " , currencyTimeLimit = 15 , persistPolicy = " OnUpdate " , persistPeriod = 200 ,
13 persistLocation = " foo " , persistName = " bar " )
14 public class AnnotationTestBean {
15
16 private String name;
17 private int age;
18
19 private List < String > values;
20
21 // 把getter或setter标记为JMX的属性
22 @ManagedAttribute(description = " The Age Attribute " , currencyTimeLimit = 1 )
23 public int getAge() {
24 return age;
25 }
26
27 public void setAge( int age) {
28 this .age = age;
29 }
30
31 @ManagedAttribute(description = " The values Attribute " , currencyTimeLimit = 1 )
32 public List < String > getValues() {
33 values = new ArrayList < String > ( 2 );
34 values.add( " hello " );
35 values.add( " world " );
36 return values;
37 }
38
39 @ManagedAttribute(description = " The Name Attribute " ,
40 currencyTimeLimit = 20 ,
41 defaultValue = " bar " ,
42 persistPolicy = " OnUpdate " )
43 public void setName(String name) {
44 this .name = name;
45 System.out.println( " set: " + name);
46 }
47
48 @ManagedAttribute(defaultValue = " foo " , persistPeriod = 300 )
49 public String getName() {
50 System.out.println( " get: " + name);
51 return name;
52 }
53
54 // 把方法标记为JMX的操作
55 @ManagedOperation(description = " Add two numbers " )
56 @ManagedOperationParameters({
57 @ManagedOperationParameter(name = " x " , description = " The first number " ),
58 @ManagedOperationParameter(name = " y " , description = " The second number " )})
59 public int add( int x, int y) {
60 return x + y;
61 }
62
63 public void dontExposeMe() {
64 throw new RuntimeException();
65 }
66 }
67
这里你可以看到,用属性
ManagedResource
来标记类
JmxTestBean
, 这个
ManagedResource
是用一系列属性来配置的。 这些属性用于配置由
MBeanExporter
产生的MBean的输出。
接下来,配置xml,来配置 MBeanExporter
1
<
beans
xmlns
="http://www.springframework.org/schema/beans"
2 xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
3 xmlns:context ="http://www.springframework.org/schema/context"
4 xsi:schemaLocation ="
5 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
6 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.0.xsd" >
7
8 < bean id ="exporter"
9 class ="org.springframework.jmx.export.MBeanExporter" >
10 < property name ="assembler" ref ="assembler" />
11 < property name ="namingStrategy" ref ="namingStrategy" />
12 < property name ="autodetect" value ="true" />
13 </ bean >
14
15 < bean id ="jmxAttributeSource"
16 class ="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
17
18 <!-- will create management interface using annotation metadata -->
19 < bean id ="assembler"
20 class ="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler" >
21 < property name ="attributeSource" ref ="jmxAttributeSource" />
22 </ bean >
23
24 <!-- will pick up ObjectName from annotation -->
25 < bean id ="namingStrategy"
26 class ="org.springframework.jmx.export.naming.MetadataNamingStrategy" >
27 < property name ="attributeSource" ref ="jmxAttributeSource" />
28 </ bean >
29
30 < bean id ="testBean"
31 class ="AnnotationTestBean" >
32 < property name ="name" value ="TEST" />
33 < property name ="age" value ="100" />
34 </ bean >
35
36
37
38 </ beans >
2 xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
3 xmlns:context ="http://www.springframework.org/schema/context"
4 xsi:schemaLocation ="
5 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
6 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.0.xsd" >
7
8 < bean id ="exporter"
9 class ="org.springframework.jmx.export.MBeanExporter" >
10 < property name ="assembler" ref ="assembler" />
11 < property name ="namingStrategy" ref ="namingStrategy" />
12 < property name ="autodetect" value ="true" />
13 </ bean >
14
15 < bean id ="jmxAttributeSource"
16 class ="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
17
18 <!-- will create management interface using annotation metadata -->
19 < bean id ="assembler"
20 class ="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler" >
21 < property name ="attributeSource" ref ="jmxAttributeSource" />
22 </ bean >
23
24 <!-- will pick up ObjectName from annotation -->
25 < bean id ="namingStrategy"
26 class ="org.springframework.jmx.export.naming.MetadataNamingStrategy" >
27 < property name ="attributeSource" ref ="jmxAttributeSource" />
28 </ bean >
29
30 < bean id ="testBean"
31 class ="AnnotationTestBean" >
32 < property name ="name" value ="TEST" />
33 < property name ="age" value ="100" />
34 </ bean >
35
36
37
38 </ beans >
接下来,编写一个测试代码看一下效果
1
import
org.springframework.context.support.ClassPathXmlApplicationContext;
2
3
4 public class Main {
5
6
7 /**
8 * @param args
9 * @throws InterruptedException
10 */
11 public static void main(String[] args) throws InterruptedException {
12
13 ClassPathXmlApplicationContext context;
14
15 context = new ClassPathXmlApplicationContext( " run.xml " );
16
17 context.start();
18
while (true) {
Thread.sleep(10000);
}
19 }
20
21 }
2
3
4 public class Main {
5
6
7 /**
8 * @param args
9 * @throws InterruptedException
10 */
11 public static void main(String[] args) throws InterruptedException {
12
13 ClassPathXmlApplicationContext context;
14
15 context = new ClassPathXmlApplicationContext( " run.xml " );
16
17 context.start();
18
while (true) {
Thread.sleep(10000);
}
19 }
20
21 }
注: 在运行的时候,需要在Jvm 加上参数"-Dcom.sun.management.jmxremote",否则就不能通过JConsole来查看 JMX 输出情况。
接下就可以运行 JConsole 就可以查看到结果。
附:Annotation 说明:
目的 | Commons Attributes属性 | JDK 5.0 注解 | 属性 / 注解类型 | |
---|---|---|---|---|
把 Class 所有的实例标记为由JMX管理的资源 |
ManagedResource |
@ManagedResource |
类 | |
把方法标记为JMX的操作 | ManagedOperation |
@ManagedOperation |
方法 | |
把getter或setter标记为JMX的半个属性 | ManagedAttribute |
@ManagedAttribute |
方法(仅 getters 和 setters) | |
定义描述操作参数 | ManagedOperationParameter |
@ManagedOperationParameter 和 @ManagedOperationParameters |
@ManagedOperationParameter 和 @ManagedOperationParameters |
方法 |
接下来的配置参数可以用于这些源码级的元数据类型:
表 20.3. 源码级的元数据参数
参数 | 描述 | 适用于 |
---|---|---|
ObjectName |
由类 MetadataNamingStrategy 使用,决定一个管理资源的 ObjectName 。 |
ManagedResource |
description |
设置资源、属性或操作友好的描述 | ManagedResource 、 ManagedAttribute 、 ManagedOperation 、 ManagedOperationParameter |
currencyTimeLimit |
描述符字段,用于设置 currencyTimeLimit 的值 |
ManagedResource 、ManagedAttribute |
defaultValue |
描述符字段,用于设置 defaultValue 的值 |
ManagedAttribute |
log |
描述符字段,用于设置 log 的值 |
ManagedResource |
logFile |
描述符字段,用于设置 logFile 的值 |
ManagedResource |
persistPolicy |
描述符字段,用于设置 persistPolicy 的值 |
ManagedResource |
persistPeriod |
描述符字段,用于设置 persistPeriod 的值 |
ManagedResource |
persistLocation |
描述符字段,用于设置 persistLocation 的值 |
ManagedResource |
persistName |
描述符字段,用于设置 persistName 的值 |
ManagedResource |
name |
设置一个操作参数的显示名字 | ManagedOperationParameter |
index |
设置操作参 |
注: 本文大部分内容来自 Spring参考文档,如果需要了解更多知识,请参见Spring refrence.
Good Luck!
Yours Matthew!