spring的JMX支持使你可以将你的Spring应用程序集成到JMX框架中。
特别是,Spring的JMX支持提供了四个核心功能:
这些功能设计成无需将你的应用程序组件结合到Spring或者JMX的接口和类上。事实上,对于大多数应用程序部分,不需要关注Spring或JMX,而充分利用Spring的JMX功能。
24.2 暴露beans给JMX
Spring的JMX框架的核心类是MBeanExporter
。这个类用于获取你的Spring beans并以一个JMXMBeanServer
注册它们。例如,考虑下面的例子:
为暴露这个bean的属性和方法,作为一个MBean的属性和操作,你仅仅在你的配置文件中配置MBeanExporter
类的实例,并在那个bean中传递。
exporter
bean。beans属性告诉
MBeanExporter
,哪个bean将暴露给JMX的
MBeanServer
。在默认的配置中,在
beans
Map
中的每条记录的关键字用作bean的
ObjectName
,并涉及到对应的记录值。
在这个配置中,testBean
在ObjectName
bean:name=testBean1以一个MBean暴露。默认地,这个bean的所有属性以元素暴露并且这个bean的所有方法(除了那些从Object类中继承的)以操作暴露。
注意
MBeanExporter
是个有声明周期的bean,并且在应用程序生命周期期间,默认地,竟可能晚的输出MBeans。
24.2.1 创建一个MBeanServer
上述的配置假设应用程序运行在一个环境中,其有且只有一个MBeanServer在运行。在这种情况下,Spring将尝试定位运行的MBeanServer并且在那个服务器上注册你的beans(如果有服务器的话)。当应用程序运行在容器内部时,这个行为是很有用的,比如Tomcat或者IBM的WebSphere都有自己的MBeanServer。
然而,这种方式在一个独立的环境中是无用的,或者当运行在一个容器内部,是不提供MBeanServer。为寻址这个,你可以分开创建一个MBeanServer,通过添加org.springframework.jmx.support.MBeanServerFactoryBean的一个实例到你的配置中。你也可以确保一个指定的MBeanServer,通过MBeanExporter的server属性的值设置为MBeanServer的值,其由MBeanServerFactoryBean返回。例如:
对于这些情况,存在的MBeanServer有一个动态的(或者未知的)agentId,其将通过lookup方法重新获取,应该使用factory-method:
24.2.3 Lazy-initialized MBeans
如果你为MBeanExporter配置了一个bean,那也需要配置延迟初始化,之后MBeanExporter将不会打破这个约束并避免初始化这个bean。另外,使用MBeanServer注册了一个代理,并推迟从容器中获取这个bean,直到这个代理进行了第一次调用。
24.2.4 自动注册MBeans
任何通过MBeanExporter输出和已经有效的MBeans,注册为MBeanServer而无需Spring更多的参与。MBeans可以通过设置autodetect为true,通过MBeanExporter自动分发。
这里,叫做spring:mbean=true的bean已经是一个有效的JMX MBean并将自动由Spring完成注册。默认地,针对JMX注册器自动分发的beans将它们的bean 名字作为ObjectName。这个行为可以重写的。
24.2.5 控制注册器行为
考虑这个场景,一个Spring的MBeanExporter尝试使用ObjectName 'bean:name=testBean1'向一个MBeanServer注册一个MBean。如果一个MBean实例已经注册了相同的ObjectName,默认行为就是失败(并抛出异常InstanceAlreadyExistsException)。
当Mbean注册到一个MBeanServer时,是可以控制所发生的行为的。Spring的XML支持允许三个不同的注册行为来控制这些,当注册动作发现一个Mbean已经注册了同样的ObjectName时;这些注册行为总结如下:
注册行为表:
注册动作 解释
REGISTRATION_FAIL_ON_EXISTING 这是默认的注册行为。如果一个Mbean实例注册了相同的ObjectName,已经注册的Mbean将不会再注册,并抛出异常InstanceAlreadyExistsException。已经存在的Mbean不受影响
REGISTRATION_IGNORE_EXISTING 如果一个Mbean实例注册了相同的ObjectName,将要注册的Mbean将不被注册。已经存在的Mbean不受影响,并不抛出异常。这在多应用程序中在一个共享的MBeanServer中共享一个通用的MBean是很有用的。
REGISTRATION_REPLACE_EXISTING 如果一个Mbean实例注册了相同的ObjectName,预先注册已经存在的MBean将不被注册并且新的Mbean将注册在前者的位置上(新的Mbean替代之前的实例)
上述值以常量值定义在MBeanRegistrationSupport类中(MBeanExporter源于这个父类)。如果你想改变这个默认的注册行为,你仅仅需要在你的MBeanExporter定义上设置registrationBehaviorName属性的值为那些值中的一个。
下面的例子演示了如何改变默认的注册行为为REGISTRATION_REPLACE_EXISTING行为