使用Spring将POJO公开为JMX MBean
(注意:对原始帖子进行了少量编辑以提高可读性)
Java管理扩展(JMX)技术是一种检查或更改变量状态或通过(例如) JConsole之类的管理GUI在(远程)运行的应用程序中调用方法的好方法。 Spring使得在几分钟之内仅用很少的配置就可以将任何POJO公开为JMX MBean变得微不足道。 Spring JMX文档非常好,但是有一段时间我一直在挣扎,因此想在这里记录正确的解决方案。
我需要在服务器上运行的IBM JVM 1.5上使用Spring 2.5监视命令行Java应用程序。 监视将在Sun JVM 1.6上使用jconsole作为PC上的JMX客户端执行。 以下所有XML片段均来自相应的Spring application-context.xml。
将POJO变成MBean
JMX可以公开以原语或复杂数据类型为参数的getter,setter和操作(尽管除少数特殊类型外,其他类型都要求客户端具有类)。 您告诉Spring将POJO公开为MBean,如下所示:
<bean id="myMBean"class="my.package.JobPerformanceStats"factory-method="instance" /><bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false"><property name="beans"><map><entry key="bean:name=MyMBeanName" value-ref="myMBean"/></map></property>
</bean>
首先,您声明一个POJO类的实例– myMBean(由于其他原因,我拥有老式的单例,并使用JobPerformanceStats.instance()访问Bean)。 接下来,使用lazy-init =“ false”声明一个MBeanExporter并向其介绍您的bean。 (还有其他方法可以执行此操作,包括自动发现。)然后,该bean将在其键(即“ bean:name = MyMBeanName”)下可见,JConsole将其显示为“ MyMBeanName”。
注意,由于MBeanExporter使用新的java.lang.management包,因此它仅在JVM 1.5+下工作。 在JDK 1.4下,Spring会因以下错误而失败:
java.lang.NoClassDefFoundError:javax / management / MBeanServerFactory
在org.springframework.jmx.support.MBeanServerFactoryBean.createMBeanServer处
默认情况下,它将公开所有公共方法和属性。 您可以通过多种方式进行更改,例如在界面的帮助下。
如果您不是在已经提供了MBean服务器的容器中运行(在这里就是我的情况),则必须告诉Spring启动一个容器:
<bean class="org.springframework.jmx.support.MBeanServerFactoryBean"/>
启用远程访问
要使MBean可从另一台机器访问,必须通过声明配置有适当通信机制的ConnectorServerFactoryBean将其公开。
通过JMXMP进行远程访问
默认情况下, ConnectorServerFactoryBean通过JMX消息传递协议(JMXMP)使用地址公开MBean。
服务:jmx:jmxmp:// localhost:9875
<bean class="org.springframework.jmx.support.ConnectorServerFactoryBean" />
但是,现成的协议不支持此协议,因此必须在MBean应用程序和jconsole客户端的类路径上都包含OpenDMK的一部分jmxremote_optional.jar(这是OpenDMK的一部分),以避免出现以下异常:
org.springframework.beans.factory.BeanCreationException:创建名称为'org.springframework.jmx.support.ConnectorServerFactoryBean#0的bean时出错? 在类路径资源[application-context.xml]中定义:初始化方法的调用失败; 嵌套的异常是java.net.MalformedURLException:不支持的协议:jmxmp
通过RMI进行远程访问
或者,您可以通过RMI公开MBean,而没有其他依赖项:
<!--
Now expose the server for remote access via RMI
Local access: service:jmx:rmi://localhost/jndi/rmi://localhost:10099/myconnector
Remote access: service:jmx:rmi:///jndi/rmi://your.host:10099/myconnector
or service:jmx:rmi://localhost/jndi/rmi://localhost:10099/myconnector
-->
<beanclass="org.springframework.jmx.support.ConnectorServerFactoryBean"depends-on="rmiRegistry"><property name="objectName" value="connector:name=rmi" /><property name="serviceUrl"value="service:jmx:rmi://localhost/jndi/rmi://localhost:10099/myconnector" />
</bean><bean id="rmiRegistry"class="org.springframework.remoting.rmi.RmiRegistryFactoryBean"><property name="port" value="10099" />
</bean>
但是,还必须避免一些陷阱:
1.必须启动RMI注册表,以便连接器可以在此处注册MBean。 它不会为你开始
2.您必须确保在连接器尝试使用之前启动注册表,方法是在连接器之前声明注册表,或者通过使用depends-on属性使此依赖关系显式
如果未正确设置,则会出现如下异常:
org.springframework.beans.factory.BeanCreationException:创建名称为'org.springframework.jmx.support.ConnectorServerFactoryBean#0的bean时出错? 在类路径资源[application-context.xml]中定义:初始化方法的调用失败; 嵌套异常是java.io.IOException:无法绑定到URL [rmi:// localhost:10099 / jmxrmi]:javax.naming.ServiceUnavailableException [根本异常是java.rmi.ConnectException:连接被拒绝托管给主机:localhost; 嵌套的异常是:java.net.ConnectException:拒绝连接:connect]。
通过SSH隧道访问的本地MBean服务器
为了提高安全性,您可能不希望通过仅从本地计算机(127.0.0.1)访问MBean并使用SSH隧道使MBean暴露给远程访问,以便远程JConsole可以将它们作为本地应用程序进行访问。 这当然是可能的,但可能会很困难,因为通常JMX会通过RMI进行访问,RMI 使用两个端口 :一个用于RMI Registry,另一个用于实际服务(此处为MBean服务器),通常在运行时随机选择,而您d需要同时隧穿。 幸运的是, Spring使配置两个端口成为可能 :
<beanclass="org.springframework.jmx.support.ConnectorServerFactoryBean"depends-on="rmiRegistry"><property name="objectName" value="connector:name=rmi" /><property name="serviceUrl"value="service:jmx:rmi://127.0.0.1:STUBPORT/jndi/rmi://localhost:REGISTRYPORT/myconnector" />
</bean><bean id="rmiRegistry"class="org.springframework.remoting.rmi.RmiRegistryFactoryBean"><property name="port" value="REGISTRYPORT" />
</bean>
将STUBPORT和REGISTRYPORT替换为合适的编号,然后隧道传输这两个编号。 请注意,连接器的serviceUrl和RMI注册表的端口属性中的REGISTRYPORT号相同。
警告:上面的配置实际上并不能阻止从远程应用程序直接访问。 为了真正强制RMI注册表仅侦听来自本地主机的连接,我们可能需要在不带Spring的Sun JVM下设置系统属性com.sun.management.jmxremote。 另外,要强制注册表使用IP 120.0.0.1,我们需要设置java.rmi.server.hostname = localhost(也适用于Spring)。 请参阅有关强制本地访问的讨论 。 我不确定如何使用Spring获得相同的结果,同时仍然保留指定两个RMI端口的功能。 还要检查Spring RmiServiceExporter的JavaDoc。
相关文章和文档:
- Alfresco的隧道调试和JMX (A。使用Spring)-请参见第二部分,JMX的SSH隧道
- 自定义隧道RMI代理 –使用配置的端口而不是随机端口
- 使用SSH上的JMX监视ActiveMQ
- JMX 1.2规范和JMX 1.2远程API规范 ; 来自JMX规范:“ MBean服务器依赖协议适配器和连接器,以使代理可以从代理JVM之外的管理应用程序访问代理。” 另一方面, Oracle JMX页面显示,如果您设置com.sun.management.jmxremote(而不是…jmxremote.port),则可以“监视本地Java平台,即在JVM上运行”。同一台机器” –因此不一定来自同一JVM。
与Jconsole连接
启动JConsole并键入适当的远程地址,例如
服务:jmx:rmi:/// jndi / rmi://your.server.com:10099 / myconnector
如果连接到远程计算机上的应用程序,则可以通过RMI访问your.server.com。
关于连接URL,如果您有一个连接器,其serviceUrl为
服务:jmx:rmi:// myhost:9999 / jndi / rmi:// localhost:10099 / myconnector
然后,可以从客户使用
服务:jmx:rmi:// myhost:9999 / jndi / rmi://your.server.com:10099 / myconnector
或简单地
服务:jmx:rmi:/// jndi / rmi://your.server.com:10099 / myconnector
因为,根据JMX 1.2远程API规范(第90页):
…主机名和端口号
#(示例中为myhost:9999)不被客户端使用,如果
#当前,本质上是注释。 连接器服务器地址
#实际上存储在序列化的存根(/ stub /形式)或
#目录条目(/ jndi /格式)。
IBM JVM,JConsole和JMX配置
IBM JVM 5 SDK指南指出IBM SDK也包含JConsole并识别与JMX相关的相同系统属性 ,即com.sun.management.jmxremote。*(尽管未提及“ com.sun.management.jmxremote”本身)。 )。
请注意,IBM JConsole有点不同,例如,它缺少“本地”选项卡,而通过指定命令行选项connection = localhost来代替它(在SDK指南中搜索“ JConsole监视工具的“本地选项卡””)。
进一步改进
JVM 1.5:公开MemoryMXBean
从Java 5.0开始,有几个有用的平台MBean提供有关JVM的信息,还包括java.lang.management.MemoryMXBean,可让您查看堆使用情况,调用GC等。
您可以按如下所示将其提供给JConsole和其他JMX代理使用(尽管必须有一种更简单的方法):
<bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false"><property name="beans"><map><entry key="bean:name=Memory2" value-ref="memProxy"/><!-- other exported beans may follow ... --></map></property>
</bean><bean id="memProxy"class="java.lang.management.ManagementFactory"factory-method="getMemoryMXBean"/>
更新:通过使用工厂方法getPlatformMBeanServer将Spring的MBeanServerFactoryBean替换为java.lang.management.ManagementFactory,似乎确实存在直接暴露平台MBean的更好的方法。 当然,这需要JVM 1.5+。
通过密码验证提高安全性
通过RMI访问MBean可能受密码保护。 根据讨论, 身份验证是在服务器连接器上配置的 :
<beanclass="org.springframework.jmx.support.ConnectorServerFactoryBean"depends-on="rmiRegistry"><property name="objectName" value="connector:name=rmi" /><property name="serviceUrl"value="service:jmx:rmi://localhost/jndi/rmi://localhost:10099/myconnector" /><property name="environment"><!-- the following is only valid when the sun jmx implementation is used --><map><entry key="jmx.remote.x.password.file" value="etc/security/jmxremote.password"/><entry key="jmx.remote.x.access.file" value="etc/security/jmxremote.access"/></map></property>
</bean>
passwd和access文件遵循可在JDK / jre / lib / management文件夹中找到的模板。
摘要
使用Spring将POJO作为MBean公开很容易,只是不要忘记启动MBean服务器和连接器。 对于JMXMP,请包括jmxmp_impl。 在类路径上的jar以及对于RMI,请确保在连接器之前启动RMI注册表。
相关文章:
- JBoss 4.2.x Spring 3 JPA Hibernate教程
- GWT EJB3 Maven JBoss 5.1集成教程
- 调试生产服务器– Eclipse和JBoss展示
翻译自: https://www.javacodegeeks.com/2011/02/expose-pojo-jmx-mbean-spring.html
使用Spring将POJO公开为JMX MBean相关推荐
- spring pojo_使用Spring将POJO公开为JMX MBean
spring pojo 这是一个非常不错的教程,介绍了如何通过我们最新的JCG合作伙伴 " The Holy Java "博客(很酷的名字)实现" 用Spring轻松将P ...
- springMVC问题XXX is not mapped [from XX]或者Unknown entity: com.spring.main.pojo.Person
springMVC问题XXX is not mapped [from XX]或者Unknown entity: com.spring.main.pojo.Person 这个问题搞了一天到凌晨才发现一个 ...
- spring 中 pojo 类为什么不需要注入
在思考这个问题之前应该需要知道什么是 IOC 和 DI .在<Spring5 高级编程>中是这样介绍它们之间的关系的: IOC 的核心是 DI,旨在提供一种更简单的机制来设置组件依赖项(通 ...
- 【Spring】SpringBoot 如何使用JMX
1.概述 在:[Spring]Spring 如何更改动态更改运行中某个类的日志级别 中最后一张图中,可以看到 程序员高手是使用JMX来操作动态修改日志级别的,下面我们就来试试. 2.jmx基本架构 在 ...
- Spring MVC POJO传参方式
有两POJO类 Address.java 1 package com.proc; 2 3 public class Address { 4 5 private String province; 6 p ...
- 在Hibernate,EhCache,Quartz,DBCP和Spring中启用JMX
继续使用JMX的过程(请参阅: 人类JMX ),我们将学习如何在一些流行的框架中启用JMX支持(通常是统计和监视功能). 这些信息大部分都可以在项目的主页上找到,但是我决定在收集这些信息的同时,很少添 ...
- 通过SPANN方式将Spring&Quartz与自定义注释集成
在上一篇文章中 ,我们演示了如何在Spring容器中创建和配置带批注的Quartz作业. 我们使用了一个类级别的注释将一些元数据添加到实现Quartz Job的bean中. 批注定义了作业的名称,组及 ...
- spring mvc 教程_Spring MVC开发–快速教程
spring mvc 教程 这是我们的JCG合作伙伴之一,来自Manoj的有关使用Spring开发Web应用程序的简短教程, 网址为" The Khangaonkar Report &quo ...
- 使用SPANN方式将Spring&Quartz与自定义注释集成
在上一篇文章中 ,我们演示了如何在Spring容器中创建和配置带批注的Quartz作业. 我们使用了一个类级别的注释将一些元数据添加到实现Quartz Job的bean中. 批注定义了作业的名称,组及 ...
最新文章
- elasticsearch安装与配置介绍
- linux下screen工具使用
- apache 网站跳转至同一页面(可用于当网站在备案时显示告示)
- java rmi 超时_java RMI服务超时
- 使用Spring Security对RESTful服务进行身份验证
- 初学Spring Boot
- celery AttributeError: 'str' object has no attribute 'items'
- java redis rpush_Redis Rpush 命令
- 机器人领域会议期刊特点
- 零基础学cad要多久_完整版的CAD技巧!3天轻松玩转CAD,零基础也能学会
- 如何让搜狗快速收录网站的技巧和方法
- [转载] 网络游戏程序员须知 调试多人联机游戏
- Eclipse官网下载
- CreateProcess 的正确关闭
- SSM毕设项目宠物医院预约管理系统wjz80(java+VUE+Mybatis+Maven+Mysql)
- CSDN-迪米特法则
- 上传文件到github上的两种方式
- 【宝塔面板】紧急安全更新通知
- 莫烦pytorch学习笔记5
- 淘域网域名交易平台推已备案未注册域名服务
热门文章
- ui自动化测试测试报告_您需要了解的有关UI测试的所有信息
- jdk10与jdk9的区别_JDK 8与JDK 10:三元/拆箱的区别
- xp系统 javafx_使用JavaFX构建React系统
- sap寄售退货单_多个退货单
- java与java ee_计划Java EE 7批处理作业
- JMetro版本11.5.11和8.5.11发布
- apache camel_在WildFly中将Apache Camel和Spring添加为jboss模块
- 使用Spring Boot和GraphQL构建安全的API
- hash和hashcode_Hibernate事实:等于和HashCode
- maven 单元测试并行_并行运行单元测试