Spring之JMX

来源:互联网 发布:五大联赛数据 编辑:程序博客网 时间:2024/06/04 22:55

Spring的JMX支持使你可以将你的Spring应用程序集成到JMX框架中。

特别是,Spring的JMX支持提供了四个核心功能:

  • 任何Spring bean,作为一个JMX MBean,的自动注册功能
  • 提供了一个灵活的机制控制你的beans管理接口
  • 本地和远程MBean资源的简单代理
  • The declarative exposure of MBeans over remote, JSR-160 connectors

这些功能设计成无需将你的应用程序组件结合到Spring或者JMX的接口和类上。事实上,对于大多数应用程序部分,不需要关注Spring或JMX,而充分利用Spring的JMX功能。

24.2 暴露beans给JMX

Spring的JMX框架的核心类是MBeanExporter。这个类用于获取你的Spring beans并以一个JMXMBeanServer注册它们。例如,考虑下面的例子:

package org.springframework.jmx;public class JmxTestBean implements IJmxTestBean {    private String name;    private int age;    private boolean isSuperman;    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public void setName(String name) {        this.name = name;    }    public String getName() {        return name;    }    public int add(int x, int y) {        return x + y;    }    public void dontExposeMe() {        throw new RuntimeException();    }}


为暴露这个bean的属性和方法,作为一个MBean的属性和操作,你仅仅在你的配置文件中配置MBeanExporter类的实例,并在那个bean中传递。

<beans>    <!-- this bean must not be lazily initialized if the exporting is to happen -->    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">        <property name="beans">            <map>                <entry key="bean:name=testBean1" value-ref="testBean"/>            </map>        </property>    </bean>    <bean id="testBean" class="org.springframework.jmx.JmxTestBean">        <property name="name" value="TEST"/>        <property name="age" value="100"/>    </bean></beans>

上述配置片段中相关的bean定义是exporterbean。beans属性告诉MBeanExporter,哪个bean将暴露给JMX的MBeanServer。在默认的配置中,在beansMap中的每条记录的关键字用作bean的ObjectName,并涉及到对应的记录值。


在这个配置中,testBeanObjectNamebean: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返回。例如:


<beans>    <bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"/>    <!--    this bean needs to be eagerly pre-instantiated in order for the exporting to occur;    this means that it must not be marked as lazily initialized    -->    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">        <property name="beans">            <map>                <entry key="bean:name=testBean1" value-ref="testBean"/>            </map>        </property>        <property name="server" ref="mbeanServer"/>    </bean>    <bean id="testBean" class="org.springframework.jmx.JmxTestBean">        <property name="name" value="TEST"/>        <property name="age" value="100"/>    </bean></beans>

这是一个由MBeanServerFactoryBean创建的MBeanServer的实例并借助server属性传递给MBeanExporter。当你传递你自己的MBeanServer实例时,MBeanExporter将不会尝试着定位一个运行的MBeanServer并将使用提供的MBeanServer实例。为了使这个正确的工作,你必须在你的系统路径上有一个JMX实现。


24.2.2 重用已经存在的MBeanServer

如果没有指定服务器,MBeanExporter尝试着自动分发一个运行的MBeanServer。这在只有一个MBeanServer实例使用的环境中有效,然而当多个实例存在的时候,exporter可能选择错误的服务器。在这样的情况下,使用者应该使用MBeanServeragentId来指定使用哪个实例。


<beans>    <bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">        <!-- indicate to first look for a server -->        <property name="locateExistingServerIfPossible" value="true"/>        <!-- search for the MBeanServer instance with the given agentId -->        <property name="agentId" value="MBeanServer_instance_agentId>"/>    </bean>    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">        <property name="server" ref="mbeanServer"/>        ...    </bean></beans>

对于这些情况,存在的MBeanServer有一个动态的(或者未知的)agentId,其将通过lookup方法重新获取,应该使用factory-method:

<beans>    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">        <property name="server">            <!-- Custom MBeanServerLocator -->            <bean class="platform.package.MBeanServerLocator" factory-method="locateMBeanServer"/>        </property>    </bean>    <!-- other beans here --></beans>



24.2.3 Lazy-initialized MBeans

如果你为MBeanExporter配置了一个bean,那也需要配置延迟初始化,之后MBeanExporter将不会打破这个约束并避免初始化这个bean。另外,使用MBeanServer注册了一个代理,并推迟从容器中获取这个bean,直到这个代理进行了第一次调用。


24.2.4 自动注册MBeans


任何通过MBeanExporter输出和已经有效的MBeans,注册为MBeanServer而无需Spring更多的参与。MBeans可以通过设置autodetect为true,通过MBeanExporter自动分发。

<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">    <property name="autodetect" value="true"/></bean><bean name="spring:mbean=true" class="org.springframework.jmx.export.TestDynamicMBean"/>


这里,叫做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行为

<beans>    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">        <property name="beans">            <map>                <entry key="bean:name=testBean1" value-ref="testBean"/>            </map>        </property>        <property name="registrationBehaviorName" value="REGISTRATION_REPLACE_EXISTING"/>    </bean>    <bean id="testBean" class="org.springframework.jmx.JmxTestBean">        <property name="name" value="TEST"/>        <property name="age" value="100"/>    </bean></beans>







0 1
原创粉丝点击