`
wenzhihua1983
  • 浏览: 81486 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Mbean的管理接口

    博客分类:
  • java
阅读更多

转载:http://www.51chm.com/spring/ch20s03.shtml

http://www.51chm.com/spring/ch20s02.shtml

在Spring的JMX框架中,核心类是 MBeanExporter。这个类负责获取Spring的bean,并用一个JMX MBeanServer 类来注册它们。举个例子,考虑下面的类:

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();
    }
}

你只需要在配置文件里简单地配置一个 MBeanExporter 的实例,并以如下所示的方法将这个bean传入,就可以将这个bean的属性和方法作为一个MBean的属性和操作暴露出去。

<beans></beans>

<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定义相关的是 exporter bean,属性 beans 是告诉类 MBeanExporter 必须将哪些bean输出到JMX的 MBeanServer 去。 缺省配置中,在 beans 中,Map 用到的每个条目的key被用做相应条目值所引用的bean的 ObjectName。 在 第 20.4 节 “控制bean的 ObjectName 中描述的情况下,可以改变这个行为。

在这项配置中,testBean 这个bean在 ObjectName值为 bean:name=testBean1 的情况下作为MBean暴露出去的。缺省情况下,这个bean所有的 public 的属性都作为对应MBean的属性, 这个bean所有的 public 的方法(除了那些继承自类 Object 的方法)都作为对应MBean的操作暴露出去的。

上述配置是假定应用程序运行在一个(仅有一个)MBeanServer 运行的环境中的。 这种情况下,Spring会试着查找运行中的 MBeanServer 并用这个server(如果有的话)来注册自己的bean。 在一个拥有自己的 MBeanServer 的容器中(如Tomcat或IBM WebSphere),这种行为是非常有用。

然而,在一个单一的环境,或运行在一个没有提供任何 MBeanServer 的容器里的情况下,这种方法毫无用处。 要处理这类问题,你可以在配置文件里添加一个类 org.springframework.jmx.support.MBeanServerFactoryBean 的实例来声明创建一个 MBeanServer 的实例。你也可以通过设置类 MBeanExporterserver 属性的值来确保使用一个特殊的 MBeanServer, 这个 MBeanServer 值是由一个 MBeanServerFactoryBean 返回的;例如:

<beans></beans>

  <bean class="org.springframework.jmx.support.MBeanServerFactoryBean" id="mbeanServer"></bean>

  <!---->
  <bean class="org.springframework.jmx.export.MBeanExporter" id="exporter"></bean>
    <property name="beans">
      
        <entry key="bean:name=testBean1" value-ref="testBean"></entry>
      
    </property>
    <property name="server" ref="mbeanServer"></property>
  

  <bean class="org.springframework.jmx.JmxTestBean" id="testBean"></bean>
    <property name="name" value="TEST"></property>
    <property name="age" value="100"></property>
  

这里,通过 MBeanServerFactoryBean 创建一个 MBeanServer 的实例,并通过属性server将这个实例提供给MBeanExporter。 在提供你自己的MBeanServer实例的时候,MBeanExporter 将不会去查找运行中的MBeanServer,而是使用这个提供的MBeanServer 实例。为了让它正确的工作,必须在你的类路径上有一个JMX的实现。

考虑这样一个场景,一个Spring的 MBeanExporter 试着用 ObjectName 'bean:name=testBean1' 往一个 MBeanServer 里注册一个MBean。 如果之前已经有一个 MBean 实例在同一个 ObjectName 下注册了,则缺省的行为是失败(并抛出一个 InstanceAlreadyExistsException 异常)。

当向 MBeanServer 注册一个 MBean 的时候,可以控制发生哪些行为。 Spring对JMX的支持三种不同的注册行为,当注册进程找到一个已经在同一个 ObjectName 下注册过的MBean时,以此来控制注册行为。这些注册行为总结在下面的表中:

 


上述各值(分别是 REGISTRATION_FAIL_ON_EXISTINGREGISTRATION_IGNORE_EXISTINGREGISTRATION_REPLACE_EXISTING)作为常数定义在类 MBeanRegistrationSupport 中(类 MBeanExporter 继承自这个超类)。如果你想改变缺省注册行为,只需要在你的 MBeanExporter 的定义中简单的把属性 registrationBehaviorName 设置成这些值中的一个就可以了。

下面的例子说明了如何从缺省的注册行为改变为 REGISTRATION_REPLACE_EXISTING 行为。

<beans></beans>

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

    <bean class="org.springframework.jmx.JmxTestBean" id="testBean"></bean>
        <property name="name" value="TEST"></property>
        <property name="age" value="100"></property>
    

在上一个例子中,并没有对bean的管理接口进行控制;每个bean的 所有public属性和方法分别作为JMX的属性和操作来输出。 为了更细粒度的对那些输出bean的属性和方法进行控制,这些属性和方法实际是作为JMX的属性和操作输出的,Spring JMX提供了一个全面的可扩展的机制来控制你那些bean的管理接口。

MetadataMBeanInfoAssembler 使你可以用源码级元数据来定义bean的管理接口。 元数据的读取由接口 org.springframework.jmx.export.metadata.JmxAttributeSource 封装。 Spring JMX提供了这个接口的两种实现,即开即用: 类 org.springframework.jmx.export.metadata.AttributesJmxAttributeSource针对公用属性(Commons Attributes), 而类 org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource 针对JDK5.0注解。 为了功能正常,类 MetadataMBeanInfoAssembler必须 和接口 JmxAttributeSource 的一个实现一起配置(这里 没有 缺省)。 在接下来的例子中,我们会用到公用属性元数据的方法。

要对一个输出到JMX的bean作标记,应该用属性 ManagedResource 来注解这个bean类。 在使用公用属性元数据方法的情况下,要能在包 org.springframework.jmx.metadata 中找到它。 你希望作为操作输出的每个方法必须用属性 ManagedOperation 打上标记, 你希望输出的每个属性必须用属性ManagedAttribute打上标记。 在标记属性的时候,可以忽略getter的注解,或忽略分别创建一个只写或只读属性的setter。

下例展示了用公用属性元数据对前文见过的类JmxTestBean进行标记的情况:

package org.springframework.jmx;

/**
 * @@org.springframework.jmx.export.metadata.ManagedResource
 *  (description="My Managed Bean", objectName="spring:bean=test",
 *  log=true, logFile="jmx.log", currencyTimeLimit=15, persistPolicy="OnUpdate",
 *  persistPeriod=200, persistLocation="foo", persistName="bar")
 */
public class JmxTestBean implements IJmxTestBean {

  private String name;

  private int age;


  /**
   * @@org.springframework.jmx.export.metadata.ManagedAttribute
   *   (description="The Age Attribute", currencyTimeLimit=15)
   */
  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  /**
   * @@org.springframework.jmx.export.metadata.ManagedAttribute
   *  (description="The Name Attribute",  currencyTimeLimit=20,
   *   defaultValue="bar", persistPolicy="OnUpdate")
   */
  public void setName(String name) {
    this.name = name;
  }

  /**
   * @@org.springframework.jmx.export.metadata.ManagedAttribute
   *   (defaultValue="foo", persistPeriod=300)
   */
  public String getName() {
    return name;
  }

  /**
   * @@org.springframework.jmx.export.metadata.ManagedOperation
   *  (description="Add Two Numbers Together")
   */
  public int add(int x, int y) {
    return x + y;
  }

  public void dontExposeMe() {
    throw new RuntimeException();
  }
}

这里你可以看到,用属性 ManagedResource 来标记类 JmxTestBean, 这个 ManagedResource 是用一系列属性来配置的。 这些属性用于配置由 MBeanExporter 产生的MBean的不同方面。 在后续章节 第 20.3.4 节 “源代码级的元数据类型” 中,将有更详细的说明。

你将会注意到属性 agename 是用属性 ManagedAttribute注解的, 但是在属性 age 这种情况下,只标记了getter。 这将使得这两个属性作为属性包括到管理接口中去,但属性 age 将是只读的。

最后,你会注意到方法 add(int, int) 是用 ManagedOperation 标记的, 而方法 dontExposeMe() 却不是。 这使得管理接口在使用 MetadataMBeanInfoAssembler 的时候只包含一个操作:add(int, int)

下列代码显示了如何用 MetadataMBeanInfoAssembler 配置 MBeanExporter

<beans></beans>

  <bean class="org.springframework.jmx.export.MBeanExporter" id="exporter"></bean>
    <property name="beans">
      
        <entry key="bean:name=testBean1" value-ref="testBean"></entry>
      
    </property>
    <property name="assembler" ref="assembler"></property>
  

  <bean class="org.springframework.jmx.JmxTestBean" id="testBean"></bean>
    <property name="name" value="TEST"></property>
    <property name="age" value="100"></property>
  

  <bean class="org.springframework.jmx.export.metadata.AttributesJmxAttributeSource" id="attributeSource"></bean>
    <property name="attributes">
      <bean class="org.springframework.metadata.commons.CommonsAttributes"></bean>
    </property>
  

  <bean class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler" id="assembler"></bean>
    <property name="attributeSource" ref="attributeSource"></property>
  

这里你可以看到,用类 AttributesJmxAttributeSource 的一个实例来配置一个MetadataMBeanInfoAssembler bean,并通过装配属性将它传递给 MBeanExporter。如果Spring输出MBean是利用元数据驱动管理接口,则所有这些都是必需的。

为了激活JDK5.0注解,用它来进行管理接口定义,Spring提供了一套相当于Commons Attribut属性类的注解和一个策略接口 JmxAttributeSource 的实现类 AnnotationsJmxAttributeSource, 这个类允许 MBeanInfoAssembler 来读这些注解。

下例是一个用JDK5.0注解定义管理接口的bean:

package org.springframework.jmx;

import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedAttribute;

@ManagedResource(objectName="bean:name=testBean4", description="My Managed Bean", log=true,
    logFile="jmx.log", currencyTimeLimit=15, persistPolicy="OnUpdate", persistPeriod=200,
    persistLocation="foo", persistName="bar")
public class AnnotationTestBean implements IJmxTestBean {

  private String name;
  private int age;

  @ManagedAttribute(description="The Age Attribute", currencyTimeLimit=15)
  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  @ManagedAttribute(description="The Name Attribute",
      currencyTimeLimit=20,
      defaultValue="bar",
      persistPolicy="OnUpdate")
  public void setName(String name) {
    this.name = name;
  }

  @ManagedAttribute(defaultValue="foo", persistPeriod=300)
  public String getName() {
    return name;
  }

  @ManagedOperation(description="Add two numbers")
  @ManagedOperationParameters({
    @ManagedOperationParameter(name = "x", description = "The first number"),
    @ManagedOperationParameter(name = "y", description = "The second number")})
  public int add(int x, int y) {
    return x + y;
  }

  public void dontExposeMe() {
    throw new RuntimeException();
  }
}

如你所见,跟元数据定义的基本语法相比,改变很少。这个方法在后台启动的时候稍微有点慢,因为JDK5.0注解被转成了Commons Attributes使用的类。 但是,这仅只是一次性的消耗,JDK5.0注解对编译期的检查更有好处。

与上述被注解的类有关的XML配置如下所示:

<beans></beans>
    <bean class="org.springframework.jmx.export.MBeanExporter" id="exporter"></bean>
        <property name="assembler" ref="assembler"></property>
        <property name="namingStrategy" ref="namingStrategy"></property>
        <property name="autodetect" value="true"></property>
    

    <bean class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" id="jmxAttributeSource"></bean>

    <!---->
    <bean class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler" id="assembler"></bean>
        <property name="attributeSource" ref="jmxAttributeSource"></property>
    

    <!---->
    <bean class="org.springframework.jmx.export.naming.MetadataNamingStrategy" id="namingStrategy"></bean>
        <property name="attributeSource" ref="jmxAttributeSource"></property>
    

    <bean class="org.springframework.jmx.AnnotationTestBean" id="testBean"></bean>
        <property name="name" value="TEST"></property>
        <property name="age" value="100"></property>
    

在Spring JMX中,可以使用下列源码级的元数据类型:

 


接下来的配置参数可以用于这些源码级的元数据类型:

 


为了进一步简化配置,Srping引入了接口 AutodetectCapableMBeanInfoAssembler , 它扩展接口 MBeanInfoAssembler,增加了对自动检测MBean资源的支持。 如果你用 AutodetectCapableMBeanInfoAssembler 的一个实例来配置 MBeanExporter,则允许对将要暴露给JMX的所有bean进行“表决”。

即开既用,MetadataMBeanInfoAssembler 是接口 AutodetectCapableMBeanInfo 唯一的实现, 它“表决”将所有被属性 ManagedResource 标记过的bean包含在内。 这种情况下,缺省的方法是用bean的名字作为 ObjectName,在配置中结果如下:

<beans></beans>

  <bean class="org.springframework.jmx.export.MBeanExporter" id="exporter"></bean>
    <!---->
    <property name="autodetect" value="true"></property>
    <property name="assembler" ref="assembler"></property>
  

  <bean class="org.springframework.jmx.JmxTestBean" id="testBean"></bean>
    <property name="name" value="TEST"></property>
    <property name="age" value="100"></property>
  

  <!---->
  <bean class="org.springframework.jmx.export.metadata.AttributesJmxAttributeSource" id="attributeSource"></bean>
    <property name="attributes">
      <bean class="org.springframework.metadata.commons.CommonsAttributes"></bean>
    </property>
  
  
  <!---->
  <!---->

  <bean class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler" id="assembler"></bean>
    <property name="attributeSource" ref="attributeSource"></property>
  

注意,在这个配置中,没有传给 MBeanExporter 任何bean;但是,JmxTestBean将仍被注册, 因为属性 ManagedResource 为它做了标记,并且 MetadataMBeanInfoAssembler 发现了这一点,“表决”包括了它。 这种方法唯一的问题是,JmxTestBean 的名字有商业含义。 要解决这个问题,你可以修改创建ObjectName 的缺省行为,按照 第 20.4 节 “控制bean的 ObjectName 章节中所讲的那样去定义。

除了 MetadataMBeanInfoAssembler,Spring还有 InterfaceBasedMBeanInfoAssembler, 它允许你在一系列方法的基础上约束将要输出的方法和属性,这一系列方法是由一组接口来定义的。

虽然输出MBeans的标准机制是使用接口和一个简单的命名策略,InterfaceBasedMBeanInfoAssembler 去掉了命名约定的需要而扩展了这一功能,允许你使用一个以上的接口,并且去掉了为了bean去实现MBean接口的需要。

考虑这个接口,用它为前面见过的类 JmxTestBean 定义一个管理接口:

public interface IJmxTestBean {

  public int add(int x, int y);

  public long myOperation();

  public int getAge();

  public void setAge(int age);

  public void setName(String name);

  public String getName();
}

这个接口定义了方法和属性,它们将作为JMX MBean的操作和属性输出。下面的代码展示了如何配置Spring JMX,用这个接口作为管理接口的定义:

<beans></beans>

  <bean class="org.springframework.jmx.export.MBeanExporter" id="exporter"></bean>
    <property name="beans">
      
        <entry key="bean:name=testBean5" value-ref="testBean"></entry>
      
    </property>
    <property name="assembler">
      <bean class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler"></bean>
        <property name="managedInterfaces">
          <value></value>org.springframework.jmx.IJmxTestBean
        </property>
      
    </property>
  

  <bean class="org.springframework.jmx.JmxTestBean" id="testBean"></bean>
    <property name="name" value="TEST"></property>
    <property name="age" value="100"></property>
  

你可以看到,在为任一bean构造管理接口时,InterfaceBasedMBeanInfoAssembler 被配成使用接口 IJmxTestBean。由 InterfaceBasedMBeanInfoAssembler 处理的bean是 需要实现那些用于生成JMX管理接口的接口的,明白这一点非常重要。

在上面的例子中,接口 IJmxTestBean 用于构造所有bean的所有管理接口。 许多情况下,并不想这样,你可能想对不同的bean用不同的接口。 这种情况下,你可以通过属性 interfaceMappings 传一个 Properties 的实例给 InterfaceBasedMBeanInfoAssembler, 在这里,每个实体的键都是bean的名字,每个实体的值就是用逗号隔开的用于那个bean的接口的名字列表。

如果既没有通过属性 managedInterfaces 又没有通过属性 interfaceMappings 指定管理接口,那么 InterfaceBasedMBeanInfoAssembler 将反射到bean上,使用所有被该bean实现的接口来创建管理接口。

评论

相关推荐

    [课堂课件讲解]Java微服务实践-Spring Boot 监管.pptx

    元信息类包含描述所有 MBean 管理接口的组件接口,其中包括属性、操作、通知和构造器。 在 JMX 核心 API 中,我们可以使用标准 MBeans、MXBean、动态 MBeans 和开放 MBeans 等。标准 MBeans 是一种特殊类型的 ...

    Java分布式应用学习笔记09JMX-MBean的介绍

    MBean的设计遵循一定的规范,并且实现了特定的接口,以确保所有管理组件都能以一种标准化的方式表示被管理资源。这里的“资源”涵盖了程序、日志、持久化数据、硬件、内存、网络吞吐量等多个方面。MBean通过提供这些...

    jmx 实例 rmi mbean

    MBeans可以是任何Java对象,它们暴露了管理接口,使得可以通过JMX API来访问和操作。 在本实例中,我们重点关注的是如何使用Remote Method Invocation(RMI)来实现JMX的MBean管理。RMI是一种在Java平台上进行远程...

    JMX实用例子详解(包括各种Mbean)

    Dynamic MBeans可以在运行时动态定义其管理接口;Open MBeans用于支持复杂的数据类型。 2. **MBean Server**:这是JMX架构的核心,它负责注册和管理MBeans,处理MBean之间的交互,并提供给管理工具访问MBeans的接口...

    Java管理扩展指南之MBean简介

    本课程介绍JMXAPI的基本概念,它被称之为被管理的...在MBean实例的生命周期中,管理接口都不会发生变化。MBeans可以在某种预定义的事件发生时发送通知。JMX规范定义了五种MBean:1.标准MBeans2.动态MBeans3.开放MBean

    mbean的样例代码

    MBean是可管理对象的简单表示,它允许外部工具或管理系统通过JMX接口来操作和获取应用程序的状态信息。在本示例代码中,我们将探讨如何创建和注册MBean,以及如何使用它来进行远程管理。 首先,我们来创建一个MBean...

    JMX(一)-------MBean server

    2. **Dynamic MBean**: 动态MBean没有固定的管理接口,它的管理接口是在运行时动态定义的。它需要实现`MBeanInfo`接口来提供关于MBean的信息。 3. **Open MBean**: Open MBean提供了一种标准的数据类型系统,使得...

    JMX IN ACTION(五)

    与标准MBean不同,标准MBean的管理接口在编译时即已明确声明,而动态MBean则利用元数据类来描述其管理接口。 5.1 与DynamicMBean接口协同工作 Dynamic MBean之所以能在JMX代理中被识别,是因为它们必须实现`javax....

    JMX IN ACTION(七)

    但是,与常规Dynamic MBeans不同,Model MBean的管理接口是由管理应用程序或资源外部定义,并通过setter方法插入到MBean中。 创建Model MBean的示例步骤如下: 1. 应用程序启动并找到一个JMX代理,以便通过向代理...

    JDK18-java-management-extensions-guide.pdf

    2. MBean:MBean(Managed Bean)是一种Java对象,用于封装管理信息和提供管理接口。 3. NotificationEmitter:NotificationEmitter是JMX架构中的事件源,用于发送和接收事件通知。 4. JMX Agent:JMX Agent是JMX...

    hellombean.zip_zip

    《深入理解MBean服务及其在Java管理扩展(JMX)中的应用》 MBean,全称为Managed Bean,是Java管理扩展(Java Management Extensions,简称JMX)框架中的核心概念。MBean代表了可管理的资源,它允许开发者将应用...

    东方通TongWeb7二次开发接口

    2.MBean Server:一个管理Bean服务器,用于管理和监控应用服务器的监视信息。 3.ObjectName:一种唯一标识符,用于标识MBean的名称和类型。 4.CompositeDataSupport:一种数据结构,用于存储和传输监视量信息。 5...

    基于Spring+JMX+Tomcat实现资源动态管理

    在资源动态管理方面,Spring通过其JMX支持允许开发者暴露管理接口,以便在运行时监控和调整应用程序的行为。 Java Management Extensions (JMX) 是Java平台的一个标准API,用于创建、管理和监控各种资源,如Java...

    jmx 入门文档,附有开发实例文档

    2. **动态MBean**:动态MBean不强制实现特定的MBean接口,而是实现`DynamicMBean`接口,它提供了运行时动态暴露属性和操作的能力。 3. **模型MBean**:模型MBean通过元数据描述其属性、操作和通知,这样可以更灵活...

    jmx学习整理里1

    3. Model MBeans:模型MBean是最灵活的类型,它允许将管理接口与业务逻辑分离。`ModelAgent.java`和`Car.java`展示了如何创建一个Model MBean。Model MBean通过`javax.management.modelmbean.ModelMBean`接口和一个...

    jmx入门

    MBean Server提供了一个统一的接口,使得管理工具可以与各种MBean进行交互。 3. **MBean操作和属性**:每个MBean都有一系列的操作(Operations)和属性(Attributes)。操作是对MBean执行的动作,如启动服务、停止...

    JMX官方文档 - 概览,入门,规范

    1. JMX API:包括MBean服务器接口、MBean接口、MBean信息类和连接器接口等,供开发人员创建和管理MBeans。 2. jconsole:JDK自带的图形化管理工具,通过JMX连接到目标应用程序,展示性能数据和MBean信息。 3. jinfo...

    JMX IN ACTION(四)

    标准MBean通过明确声明的管理接口暴露资源,该接口是不变的。 此外,由于这是关于MBean类型的三章中的第一章,我们还会讨论所有MBean类型共有的构建规则。完成本章后,你将对标准MBean有更深入的了解,包括如何编写...

    jmx技术介绍(ppt)

    JMX的核心概念包括MBean(Management Bean)、MBean服务器和管理接口。 **概述** JMX是Java平台的一个扩展,它定义了网络管理的规范,允许开发者创建可扩展的管理解决方案。JMX 1.4是其最新的规范版本。该技术旨在...

Global site tag (gtag.js) - Google Analytics