我一直在尝试让示例JMX MXBean在Spring配置的Web应用程序中工作,但是当我与jconsole连接时,MXBean上的所有基本属性都显示为UNDEFINED。
Java接口/类:
public interface IJmxBean { // marker interface for spring config, see below
}
public interface MgmtMXBean { // lexical convention for MXBeans - mgmt interface
public int getAttribute();
}
public class Mgmt implements IJmxBean, MgmtMXBean { // actual JMX bean
private IServiceBean serviceBean; // service bean injected by Spring
private int attribute = 0;
@Override
public int getAttribute() {
if(serviceBean != null) {
attribute = serviceBean.getRequestedAttribute();
}
return attribute;
}
public void setServiceBean(IServiceBean serviceBean) {
this.serviceBean = serviceBean;
}
}
Spring JMX配置:
<beans>
<context:component-scan base-package="...">
<context:include-filter type="assignable" expression="...IJmxBean" />
</context:component-scan>
<context:mbean-export />
</beans>
到目前为止,这是我所知道的:
该元素正确地实例化了一个名为“ mgmt”的bean。我已经登录了一个零参数的公共构造函数,该构造函数表明它已被构造。
在我的Tomcat 6.0容器中正确地自动检测并注册了MgmtMXBean接口。我可以使用jconsole连接到Tomcat中的MBeanServer,然后深入到Mgmt MXBean。
检查MXBean时,“属性”总是列为UNDEFINED,但是jconsole可以告诉属性正确的类型。此外,在jconsole中单击“刷新”实际上不会调用“属性”的getter方法-我已登录getter方法以指示是否正在调用它(类似于有效的构造方法日志记录),并且在日志中什么也看不到。
在这一点上,我不确定自己在做什么错。我已经尝试了许多方法,包括构造一个显式的Spring MBeanExporter实例并手动注册MXBean,但是它要么导致MBean / MXBean未向Tomcat的MBean服务器注册,要么导致Attribute值未定义。
由于各种原因,我不希望不必使用Spring的@ ManagedResource / @ ManagedAttribute批注。
Spring文档或MBean / MXBean规范中是否缺少某些内容?
最佳答案
已解决的问题:感谢乔恩·史蒂文斯(Jon Stevens)的提示(以上),我回过头来重新检查了我的代码和Spring配置文件:
在getAttribute()
方法中引发异常是确保“不可用”在JConsole中显示为属性值的肯定方法。就我而言:
我使用的Spring JMX配置文件在根default-autowire=""
元素上缺少<beans>
属性。
上面提供的代码检查是否为serviceBean != null
。显然,我在stackoverflow.com上编写的代码比在我的测试代码中写的更好,因为我的测试代码并未对此进行检查。我也没有像通常在使用的几乎所有其他bean上一样,用implements InitializingBean
或@PostConstruct
检查serviceBean != null
。
调用服务Bean的代码在记录之前,因此我从未看到有关输入getter方法的任何日志消息。
当属性方法抛出异常时,JConsole不会报告。
NPE没有显示在Tomcat日志中。
一旦我用serviceBean == null
解决了问题,一切都将正常运行。无论如何,请Jon +1以提供有效的演示,因为实际上有50种不同的方法可以在Spring中配置MBean / MXBean。