在Web项目中使用Spring对JMX的支持非常方便,通过简单的配置即可创建MBeanServer和注册一个普通的JavaBean为MBean。如下所示配置:
<!-- Annotation配置 --> <context:annotation-config /> <!-- 扫描包 --> <context:component-scan base-package="com.hehe.ad" /> <context:mbean-export server="mbeanServer" /> <bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"> <property name="locateExistingServerIfPossible" value="false" /> </bean>
因为是Web项目,所以直接通过org.springframework.web.context.ContextLoaderListener初始化Spring的配置,非常方便,但是我们的Agent端是一个普通的Java项目,而我们也希望使用Spring对JMX的支持,于是我使用如下方式去加载xml文件:
SpringContainer.appContext = new GenericApplicationContext( "spring-context.xml"); server.agentMbeanServer = (MBeanServer) SpringContainer.appContext .getBean("agentMbeanServer");
启动后,通过JConsole看到xml声明的MBeanServer生成了,而且我们手动注册了一个MBean也已经在那棵JMX树上了,注册方式如下:
ObjectName mletName = null; try { mletName = new ObjectName("Agent:name=mlet"); server.createMBean("javax.management.loading.MLet", mletName); } catch (Exception e) { e.printStackTrace(); }
一切顺利!
下面我们开始写一个普通的Spring的Bean对象,通过注解,看看能不能注册到MBeanServer。代码如下:
@Component @ManagedResource(objectName = "Agent:name=tomcat", description = "Tomcat Operations.", log = true, logFile = "jmx.log") public class TomcatMbean { @ManagedOperation(description = "Start Tomcat.") @ManagedOperationParameters( { @ManagedOperationParameter(name = "tomcatInfo", description = "tomcatInfo.") }) public ResultInfo start(TomcatInfo tomcatInfo) { ResultInfo result = new ResultInfo(); ASService asService = new ASService(tomcatInfo); CmdExecutor executor = ExecutorFactory .getExecutor(EXECUTOR_TYPE.SCRIPT_EXECUTOR.getTypeCode(), tomcatInfo.getId()); asService.setExecutor(executor); if (asService.start()) { result.setSuccess(true); return result; } else { result.setErrorInfo("启动Tomcat失败!"); result.setSuccess(false); return result; } }
我们通过@Component将这个TomcatMbean注册为Spring的Bean注册为Spring的一个Bean,然后通过JMX的注解来声明这个MBean,如果这些注解看不懂的话,可以参考Spring的官方文档。
奇怪的事情发生了~~
通过调试发现,这个Spring的MBean已经被注册上了,也就是说那个@Component注解生效了,但是这个JMX的注解死活不行,然后各种查文档、采用xml方式、各种使用Spring的官方文档的配置方式,反正,就是不行!
最后,将GenericApplicationContext 改成了ClassPathXmlApplicationContext ,万事ok!!郁闷死~~
其实一开始也想到这点了,但是觉得不可能就绕过去了,哎,回头还得继续读读Spring的源码~~