JMX 是Java 管理扩展(Java Management Extensions);JMX是一种管理和监控系统资源的技术。这种规范为运行管理系统体统了强大的功能。这些资源有托管Bean(managed beans,MBeans)表示。Spring 可以将任何Spring 管理的Bean输出为Mbean,而不需要在该Bean中定义任何JMX特有的属性。可以简单地通过声明一个MbeanExporter实例来完成将普通Bean 导出为Mbean.
- 如果Bean实现了任意一个JMX的管理接口 MBeanExporter可以简单地通过自动检测过程注册服务器的MBean
- 如果Bean没有实现JMX的挂历接口 MBeanExporter通过使用MBeanInfoAssembler创建管理信息
/**
*定义一个普通的接口
*
* @author zhangwei_david
* @version $Id: HiMBean.java, v 0.1 2015年1月24日 下午1:16:15 zhangwei_david Exp $
*/
public interface HiMBean {
/**
*打招呼
*/
public void sayHello();
/**
* 加法计算器
*
* @param x
* @param y
* @return
*/
public int add(int x, int y);
/**
* 获取名称
*
* @return
*/
public String getName();
/**
*获取缓存大小
*
* @return
*/
public int getCacheSize();
/**
*设置缓存大小
*
* @param size
*/
public void setCacheSize(int size);
}
/**
*简单实现类
* @author Lenovo
* @version $Id: Hi.java, v 0.1 2014年9月26日 下午2:48:09 Lenovo Exp $
*/
public class HiMbeanImpl implements HiMBean {
private final String name = "Reginald";
private int cacheSize = DEFAULT_CACHE_SIZE;
private static final int DEFAULT_CACHE_SIZE = 200;
/**
* @see com.cathy.demo.jmx.notifications.HiMBean#sayHello()
*/
public void sayHello() {
System.out.println("Hello," + getName());
}
/**
* @see com.cathy.demo.jmx.notifications.HiMBean#add(int, int)
*/
public int add(int x, int y) {
return x + y;
}
/**
* @see com.cathy.demo.jmx.notifications.HiMBean#getName()
*/
public String getName() {
return name;
}
/**
* @see com.cathy.demo.jmx.notifications.HiMBean#getCacheSize()
*/
public int getCacheSize() {
return cacheSize;
}
/**
* @see com.cathy.demo.jmx.notifications.HiMBean#setCacheSize(int)
*/
public void setCacheSize(int size) {
cacheSize = size;
}
}
/**
*
* @author zhangwei
* @version $Id: AsyncDemoTest.java, v 0.1 2014年9月26日 下午10:43:43 zhangwei Exp $
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:META-INF/spring/jmx-beans.xml")
public class JmxTest {
@Test
public void testAsync() throws InterruptedException {
TimeUnit.HOURS.sleep(1);
}
}
jconsole的结果:
如果不是用Spring导出一个Mban的化 代码如下:
/**
*
* @author Lenovo
* @version $Id: Main.java, v 0.1 2014年9月26日 下午4:08:31 Lenovo Exp $
*/
public class Main {
/**
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
//获取Mean的平台服务
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
// 对即将被注册的MBean 构造一个ObjectName
ObjectName objectName = new ObjectName("com.cathy.demo.jmx:type=Hi");
// 创建一个Mbean
RequiredModelMBean mbean = new RequiredModelMBean();
HiMbeanImpl hiMbean = new HiMbeanImpl();
mbean.setManagedResource(hiMbean, "objectReference");
ModelMBeanAttributeInfo name = new ModelMBeanAttributeInfo("name", "java.lang.String",
"userName", true, true, false, new DescriptorSupport(new String[] { "name=name",
"descriptorType=attribute", "getMethod=getName", "setMethod=setName" }));
ModelMBeanOperationInfo sayHello = new ModelMBeanOperationInfo("say Hello", hiMbean
.getClass().getMethod("sayHello"));
ModelMBeanOperationInfo getName = new ModelMBeanOperationInfo("get userName", hiMbean
.getClass().getMethod("getName"));
ModelMBeanInfo mbeanInfo = new ModelMBeanInfoSupport("HiMbean", "Test",
new ModelMBeanAttributeInfo[] { name }, null, new ModelMBeanOperationInfo[] { sayHello,
getName }, null);
mbean.setModelMBeanInfo(mbeanInfo);
// 将Mbean 注册到MBeanServer
mbs.registerMBean(mbean, objectName);
// 一直等待
System.out.println("Waiting forever...");
Thread.sleep(Long.MAX_VALUE);
}
}
为远程服务暴露一个Mbean
有时候需要将本地的Mbean暴露出去,供远程调用;在Spring可以使用ConnectorServerFactoryBean创建一个JMX连接服务器。
通过Jconsole 访问远程Mbean
已经为远程服务暴露了Mbean 那么如果在Spring 中远程调用Mbean又是什么样的呢?
/**
*
* @author zhangwei
* @version $Id: AsyncDemoTest.java, v 0.1 2014年9月26日 下午10:43:43 zhangwei Exp $
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:META-INF/spring/jmx-beans.xml")
public class JmxTest {
@Autowired
private HiMBean hiMbeanProxy;
@Test
public void testAsync() throws InterruptedException {
hiMbeanProxy.sayHello();
TimeUnit.HOURS.sleep(1);
}
}
结果是:
一月 24, 2015 2:16:34 下午 org.springframework.test.context.TestContextManager retrieveTestExecutionListeners
信息: @TestExecutionListeners is not present for class [class com.cathy.demo.schedule.JmxTest]: using defaults.
一月 24, 2015 2:16:34 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from URL [file:/H:/Alipay.com/workspace4alipay/demo/target/classes/META-INF/spring/jmx-beans.xml]
一月 24, 2015 2:16:35 下午 org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider registerDefaultFilters
信息: JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning
一月 24, 2015 2:16:35 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.GenericApplicationContext@7c703b: startup date [Sat Jan 24 14:16:35 CST 2015]; root of context hierarchy
一月 24, 2015 2:16:35 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@afc191: 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,hiMbean,mbeanExporter,rmiRegistry,connectorServer,mbeanServerConnection,hiMbeanProxy,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
一月 24, 2015 2:16:35 下午 org.springframework.jmx.export.MBeanExporter afterPropertiesSet
信息: Registering beans for JMX exposure on startup
一月 24, 2015 2:16:35 下午 org.springframework.jmx.export.MBeanExporter registerBeanInstance
信息: Located managed bean 'bean:name=hiMbean': registering with JMX server as MBean [bean:name=hiMbean]
一月 24, 2015 2:16:35 下午 org.springframework.remoting.rmi.RmiRegistryFactoryBean getRegistry
信息: Looking for RMI registry at port '1099'
一月 24, 2015 2:16:36 下午 org.springframework.remoting.rmi.RmiRegistryFactoryBean getRegistry
信息: Could not detect RMI registry - creating new one
一月 24, 2015 2:16:36 下午 org.springframework.jmx.support.ConnectorServerFactoryBean afterPropertiesSet
信息: JMX connector server started: javax.management.remote.rmi.RMIConnectorServer@9d0b9d
Hello,Reginald