Spring1.2rc1中jmx支持的一些答疑
jmx是什么?
jmx是Java下的资源治理规范。泛指的资源可以代表任何对象和事务,如网络,设备,应用程序。在这里,我们特指javabean。
jmx可以干什么?
通过jmx,可以在程序运行期改变资源的配置和状态,启动或者停止服务。对应着javabean,就是调用setter设置新的属性值,调用bean上的方法完成某些功能。比如关闭原来的数据库连接,设置一个新的数据库url,然后启动新的数据库连接,这些都是运行期的操作,不需要你停止服务器。当然,你完全可以自己编码,自己实现对bean配置的治理。事实上,假如不使用jmx也可以达到配置的目的,不过使用jmx后,可以作的更专业点
jmx在使用上的结构是怎么样的?
jmx最新的规范是1.2。从使用上来说,jmx分为两部分,服务端和客户端。被治理的资源注册到服务端,服务端可以开放某些协议和接口。客户端通过某种方式连接到服务端,根据协议执行某些操作,使得服务端更改资源的配置和状态。
当然,上面这种说法是很粗糙的,具体的细节可以查看jmx规范http://java.sun.com/prodUCts/JavaManagement/
spring和jmx集成有什么作用?
spring的最主要功能是进行ioc装配。而这个装配相对来说是静态的,一旦程序启动就需要通过其他手段来更改bean的属性。jmx就是运行时改变配置的一种方法。
spring是怎么集成jmx的?
spring对jmx的集成体现在两个方面
一方面,假如你处于编写客户端代码的情况,spring提供了org.springframework.jmx.Access 包,使得你可以很轻易的同Server连接实现治理代码。
另一方面,spring提供了org.springframework.jmx.eXPort 包。使得你不用编写任何代码,就可以将spring下治理的bean作为jmx资源注册到server中。下面我们只讨论export。
jmx中经常提到的MBean是什么?
MBean就是被jmx治理的资源。一般有两种类型的MBean,标准的和动态的。
标准类型的MBean最简单,它能治理的资源(包括属性,方法,时间)必须定义在接口中,然后MBean必须实现这个接口。它的命名也必须遵循一定的规范,例如我们的MBean为Hello,则接口必须为HelloMBean。
动态MBean必须实现javax.management.DynamicMBean接口,所有的属性,方法都在运行时定义。
Spring的export 支持那种类型的bean?我的javabean必须符合jmx规范么?
Spring支持把任何一种bean作为MBean。假如这个javabean本身就是按照jmx规范设计的MBean,spring会简单的把他注册到jmx server中。假如这个bean不是MBean,那么spring会动态创建一个MBean(事实上是一个model MBean),再把原先的这个bean设置到这个新创建的MBean。jmx server通过这个MBean间接的治理对应的资源。
假如不用spring,我可以使用jmx么?
当然可以。不过使用spring,你可以简单的和现有系统集成。你不需要编写一行代码,就能将你的应用建立在jmx基础上。
你说的都很好,我也决定使用spring对jmx的集成了,那么我怎么开始?
首先你要下载spring1.2版本,接着要找到jmx的某个实现。假如你使用的是jdk1.5,那么你已经内置了jmx功能。假如你使用的是更低的版本,那么你需要下载一个jmx的实现。一般有两个选择,下载sun的参考实现http://java.sun.com/products/JavaManagement/或者找一个更“专业”的实现,比如mx4j http://mx4j.sourceforge.net/
下面我以sun参考实现为例子。
spring中怎么配置jmx export?
java代码:
<?XML version="1.0" encoding="UTF-8"?
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"
<beans
<bean id="jmxMBeanExport" class="org.springframework.jmx.export.MBeanExporter"
<property name="server"
<beanclass="javax.management.MBeanServerFactory" factory-method="createMBeanServer"/
</property
<property name="beans"
<map
<entry key="MyAgent:name=Htmladapter,port=9092"
<bean class="com.sun.jdmk.comm.HtmlAdaptorServer" init-method="start"
<property name="port"
<value9092</value
</property
</bean
</entry
</map
</property
</bean
</beans
将这个applicationContext启动起来,然后在浏览器中打开http://localhost:9092/,你应该能看到一个jmx的治理界面。
配置文件中的HtmlAdaptorServer有双重身份,首先他是一个MBean,被jmx server治理;其次他对外打开了一个接口,可以通过他治理jmx。我们称这种MBean为Protocol adapters 或者connectors。
事实上,HtmlAdaptorServer的是放在jmxtools.jar中的。你也可以在其他jmx实现上(比如mx4j的Server)也使用这个Adaptor。这就是使用jmx的优势:有一个统一的治理平台,可以使用任何一种和标准兼容的治理工具。
我如何将自己的bean export出来?
很简单,只需要多一行entry就可以了,比如java代码:
<entry key="MyAgent:name=hello"
<ref bean="hello"/
</entry
Spring怎么知道要把我的bean中的哪些属性和方法暴露出来?
Spring其实不知道。假如你不作任何配置,那么他会采用一种很极端的方式所有的getter/setter都作为jmx中的属性,所有的public方法,都作为jmx中的方法。但是从Object下继续来的会被屏蔽,所以,你不会在jmx中看到toString这个方法。
事实上,spring是通过MBeanInfoAssembler来获取资源信息的。默认情况下他用的是SimpleReflectiveMBeanInfoAssembler。假如你有定制的要求,那么可以用其他的MBeanInfoAssembler。
我看到了org.springframework.jmx.export.annotation。这个似乎是jdk1.5 annotations 用的。我也必须使用jdk1.5么?
org.springframework.jmx.export.annotation下的这些类是确实配合annotation用的。上面说过,假如要定制暴露给jmx中的属性和方法,那么需要使用其他的MBeanInfoAssembler。其中一种方法是利用annotations。不过假如你不用到annotation,就不需要使用jdk1.5。annotations只是一个可选项
jmx和spring不能作什么?
即使你用了jmx和spring,也有很多是他们不能完成的功能,比如他们不能直接帮助你向老板要求加薪,不能阻止某些国家对海峡的干涉,更不能协助人类探索火星……
好了,回到正题,jmx和spring只是协助你完成某些功能,而且这些功能相对来说还是很有限的。首先jmx中可被治理的属性只能是一些简单类型,比如数字或者字符。其次jmx也不能自动帮你把修改后的属性保存起来。所以假如你自己不写特定的代码,下次程序启动后还是原始的配置。不过不管怎么说,有了spring和jmx,“究竟,生活更美好了些”