Spring集成JMX是很简单的,这里通过注解发方式暴露JMX,有的时序我们需要监听JMX属性的改变,下面我们在Spring配置文件中配置监听器。
涉及到三个重要的annotation:@ManagedResource @ManagedAttribute 和 @ManagedOperation。
用途 Commons Attributes属性 JDK 5.0注解 属性/注解类型
将类的所有实例标识为JMX受控资源 | ManagedResource |
@ManagedResource |
Class 类 |
将方法标识为JMX操作 | ManagedOperation |
@ManagedOperation |
Method方法 |
将getter或者setter标识为部分JMX属性 | ManagedAttribute |
@ManagedAttribute |
Method (only getters and setters) 方法(仅getters和setters) |
定义操作参数说明 | ManagedOperationParameter |
@ManagedOperationParameter 和@ManagedOperationParameters
|
Method 方法 |
ObjectName | Used by MetadataNamingStrategy to determine the ObjectName of a managed resource | ManagedResource |
description | Sets the friendly description of the resource, attribute or operation | ManagedResource, ManagedAttribute, ManagedOperation, ManagedOperationParameter |
currencyTimeLimit | Sets the value of the currencyTimeLimit descriptor field | ManagedResource, ManagedAttribute |
defaultValue | Sets the value of the defaultValue descriptor field | ManagedAttribute |
log | Sets the value of the log descriptor field | ManagedResource |
logFile | Sets the value of the logFile descriptor field | ManagedResource |
persistPolicy | Sets the value of the persistPolicy descriptor field | ManagedResource |
persistPeriod | Sets the value of the persistPeriod descriptor field | ManagedResource |
persistLocation | Sets the value of the persistLocation descriptor field | ManagedResource |
persistName | Sets the value of the persistName descriptor field | ManagedResource |
name | Sets the display name of an operation parameter | ManagedOperationParameter |
index | Sets the index of an operation parameter | ManagedOperationParameter |
AttributeChangeNotification,这个类是javax.management.Notification的子类,而javax.management.Notification
这个类又是java.util.EventObject的子类,由此可以证实上边所说的,JMX通知机制使用了观察者设计模式.
javax.management.Notification是一个JMX的通知核心类,将来需要扩展或者其他JMX自带的消息,均集成自此类.
AttributeChangeNotification根据类名可知,是一个属性改变的通知,造方法参数如下:
Object source, // 事件源,一直传递到java.util.EventObject的source
long sequenceNumber, // 通知序号,标识每次通知的计数器
long timeStamp, // 通知发出的时间戳
String msg, // 通知发送的message
String attributeName, // 被修改属性名
String attributeType, // 被修改属性类型
Object oldValue, // 被修改属性修改以前的值
Object newValue // 被修改属性修改以后的值
根据观察者模式,由事件与广播组成,所以这里继承了NotificationBroadcasterSupport,来提供广播机制,
调用NotificationBroadcasterSupportr的sendNotification(notification) 发送广播,广播会根据注册的观察者
来对观察者进行逐一通知.
/** * * @author Lenovo * @version $Id: HelloMBean.java, v 0.1 2014年9月26日 下午4:28:17 Lenovo Exp $ */ @Component @ManagedResource(description = "hello demo", objectName = "bean:name=helloTest") public class Hello extends NotificationBroadcasterSupport implements HelloMBean { private final String name = "Reginald"; private int cacheSize = DEFAULT_CACHE_SIZE; private static final int DEFAULT_CACHE_SIZE = 200; private long sequenceNumber = 1; /** * @see com.cathy.demo.jmx.notifications.HiMBean#sayHello() */ @ManagedOperation(description = "say hello") public void sayHello() { System.out.println("Hello,Word"); } /** * @see com.cathy.demo.jmx.notifications.HiMBean#add(int, int) */ @ManagedOperation(description = "add") @ManagedOperationParameters({ @ManagedOperationParameter(name = "x", description = "fist param"), @ManagedOperationParameter(name = "y", description = "second param") }) public int add(int x, int y) { return x + y; } /** * 获取 name 属性,通过gatter 方法获取私有的成员属性,在这个例子中属性值是永远不会改变的;但是对于其他的属性可能在程序的运行期间进行 * 改变。然而一些属性代表统计数据,如,如运行时间,内存使用情况等是只读到 也就是不能通过接口改变的 * @see com.cathy.demo.jmx.notifications.HiMBean#getName() */ @ManagedAttribute public String getName() { return name; } /** * 获取私有成员变量cacheSize 的值 * @see com.cathy.demo.jmx.notifications.HiMBean#getCacheSize() */ @ManagedAttribute public int getCacheSize() { return cacheSize; } /** * 设置私有成员变量cacheSize 的值 * @see com.cathy.demo.jmx.notifications.HiMBean#setCacheSize(int) */ @ManagedAttribute public void setCacheSize(int size) { int oldSize = cacheSize; System.out.println("Cache size now is " + oldSize); /** * 构建一个介绍属性改变的通知, */ Notification notification = new AttributeChangeNotification(this, sequenceNumber++, System.currentTimeMillis(), "CacheSize changed", "cacheSize", "int", oldSize, size); /** * 发送通知 */ sendNotification(notification); cacheSize = size; } /** * @see javax.management.NotificationBroadcasterSupport#getNotificationInfo() */ @Override public MBeanNotificationInfo[] getNotificationInfo() { String[] types = new String[] { AttributeChangeNotification.ATTRIBUTE_CHANGE }; String name = AttributeChangeNotification.class.getName(); String description = "An attribute of this MBean has changed"; MBeanNotificationInfo info = new MBeanNotificationInfo(types, name, description); return new MBeanNotificationInfo[] { info }; } }
通知监听器:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd "> <aop:aspectj-autoproxy /> <context:annotation-config /> <context:component-scan base-package="com.cathy.demo.jmx.*" /> <bean id="jmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" /> <bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler"> <property name="attributeSource" ref="jmxAttributeSource" /> </bean> <!-- ObjectName命名策略 --> <bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy"> <property name="attributeSource" ref="jmxAttributeSource" /> </bean> <bean id="mbeanExporter" class="org.springframework.jmx.export.MBeanExporter"> <!-- 指定messageInfo装配类 --> <property name="assembler" ref="assembler" /> <!-- 指定ObjectName命名策略 --> <property name="namingStrategy" ref="namingStrategy" /> <!-- 配置自动检测MBean --> <property name="autodetect" value="true" /> <property name="notificationListenerMappings"> <map> <entry key="*"> <bean class="com.cathy.demo.jmx.listener.ConfigNotificationListener" /> </entry> </map> </property> </bean> <bean id="fileReplicator" class="com.cathy.demo.jmx.annotation.FileReplicatorImpl" /> </beans>
/** * * @author zhangwei_david * @version $Id: ConfigNotificationListener.java, v 0.1 2015年6月19日 下午4:37:09 zhangwei_david Exp $ */ public class ConfigNotificationListener implements NotificationListener, NotificationFilter { /** */ private static final long serialVersionUID = 1099818764372891903L; /** * @see javax.management.NotificationListener#handleNotification(javax.management.Notification, java.lang.Object) */ public void handleNotification(Notification notification, Object handback) { log("SequenceNumber:" + notification.getSequenceNumber()); log("Type:" + notification.getType()); log("Message:" + notification.getMessage()); log("Source:" + notification.getSource()); log("TimeStamp:" + notification.getTimeStamp()); } private void log(String message) { System.out.println(message); } /** * @see javax.management.NotificationFilter#isNotificationEnabled(javax.management.Notification) */ public boolean isNotificationEnabled(Notification notification) { return true; } }
通过Jconsole控制台可以看到如下信息:
修改cacheSize 在eclipse的控制台可以看到如下日志:
log4j:WARN custom level class [# 输出DEBUG级别以上的日志] not found. 2015-06-21 13:42:55 [ main:0 ] - [ INFO ] @TestExecutionListeners is not present for class [class com.cathy.demo.jmx.AutoDetectJmxTest]: using defaults. 2015-06-21 13:42:56 [ main:137 ] - [ INFO ] Loading XML bean definitions from URL [file:/H:/Alipay.com/workspace4alipay/demo/target/classes/META-INF/spring/jmx-annotation-beans.xml] 2015-06-21 13:42:56 [ main:369 ] - [ INFO ] JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning 2015-06-21 13:42:56 [ main:421 ] - [ INFO ] Refreshing org.springframework.context.support.GenericApplicationContext@15f7ae5: startup date [Sun Jun 21 13:42:56 CST 2015]; root of context hierarchy 2015-06-21 13:42:56 [ main:580 ] - [ INFO ] Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@40cd94: defining beans [org.springframework.aop.config.internalAutoProxyCreator,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,hello,jmxAttributeSource,assembler,namingStrategy,mbeanExporter,fileReplicator,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy 2015-06-21 13:42:56 [ main:693 ] - [ INFO ] Registering beans for JMX exposure on startup 2015-06-21 13:42:56 [ main:695 ] - [ INFO ] Bean with name 'hello' has been autodetected for JMX exposure 2015-06-21 13:42:56 [ main:705 ] - [ INFO ] Bean with name 'fileReplicator' has been autodetected for JMX exposure 2015-06-21 13:42:56 [ main:707 ] - [ INFO ] Located MBean 'hello': registering with JMX server as MBean [bean:name=helloTest] 2015-06-21 13:42:56 [ main:709 ] - [ INFO ] Located managed bean 'fileReplicator': registering with JMX server as MBean [com.cathy.demo.jmx.annotation:name=fileReplicator,type=FileReplicatorImpl] Cache size now is 200 SequenceNumber:1 Type:jmx.attribute.change Message:CacheSize changed Source:bean:name=helloTest TimeStamp:1434865528473
相关推荐
第18章 使用JMX监控Spring本章内容:使用Actuator端点的MBean将Spring bean暴露为MBean发布通知JMX(Java Manage
12.4.1将springbean输出为mbean 12.4.2远程访问mbean 12.4.3处理通知 12.5小结 第三部分spring客户端 第13章处理web请求 13.1开始springmvc之旅 13.1.1请求生命中的一天 13.1.2配置dispatcherservlet ...
12.4.1 将Spring Bean输出为MBean 12.4.2 远程访问MBean 12.4.3 处理通知 12.5 小结 第三部分 Spring客户端 第13章 处理Web请求 13.1 开始Spring MVC之旅 13.1.1 请求生命中的一天 13.1.2 配置...
12.4.1 将Spring Bean输出为MBean 12.4.2 远程访问MBean 12.4.3 处理通知 12.5 小结 第三部分 Spring客户端 第13章 处理Web请求 13.1 开始Spring MVC之旅 13.1.1 请求生命中的一天 13.1.2 配置...
1. 简介 1.1. 概览 1.2. 使用场景 2. Spring 2.0 的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 更简单的XML配置 2.2.2. 新的bean作用域 2.2.3. 可扩展的XML编写 ... 将 Spring Beans 注入到 Tapestry ...
20.2. 输出bean到JMX 20.2.1. 创建一个MBeanServer 20.2.2. 复用现有的MBeanServer 20.2.3. MBean的惰性初始化 20.2.4. MBean的自动注册 20.2.5. 控制注册行为 20.3. 控制bean的管理接口 20.3.1. ...
2.6.4. 将Spring 应用程序上下文部署为JCA adapter 2.6.5. 计划任务 2.6.6. 对Java 5 (Tiger) 支持 2.7. 移植到Spring 2.5 2.7.1. 改变 2.8. 更新的样例应用 2.9. 改进的文档 I. 核心技术 3. IoC(控制反转)...
3.12 将Spring Bean注入领域对象 147 3.12.1 问题 147 3.12.2 解决方案 147 3.12.3 工作原理 148 3.13 小结 151 第4章 Spring中的脚本 152 4.1 用脚本语言实现Bean 152 4.1.1 问题 152 4.1.2 解决...
2.6.4. 将Spring 应用程序上下文部署为JCA adapter 2.6.5. 计划任务 2.6.6. 对Java 5 (Tiger) 支持 2.7. 移植到Spring 2.5 2.7.1. 改变 2.8. 更新的样例应用 2.9. 改进的文档 I. 核心技术 3. IoC(控制反转)...
Spring Framework 开发参考手册 Rod Johnson Juergen Hoeller Alef Arendsen Colin Sampaleanu Rob Harrop Thomas Risberg Darren Davison Dmitriy Kopylenko Mark Pollack Thierry Templier Erwin ...
3.12 将Spring Bean注入领域对象 147 3.12.1 问题 147 3.12.2 解决方案 147 3.12.3 工作原理 148 3.13 小结 151 第4章 Spring中的脚本 152 4.1 用脚本语言实现Bean 152 4.1.1 问题 152 4.1.2 解决...
52.1. Customizing MBean Names 52.2. Disabling JMX Endpoints 52.3. Using Jolokia for JMX over HTTP 52.3.1. Customizing Jolokia 52.3.2. Disabling Jolokia 53. Loggers 53.1. Configure a Logger 54. Metrics...
将Spring Data仓库暴露为REST端点 vii. 68. 数据库初始化 i. 68.1. 使用JPA初始化数据库 ii. 68.2. 使用Hibernate初始化数据库 iii. 68.3. 使用Spring JDBC初始化数据库 iv. 68.4. 初始化Spring Batch数据库 v. ...