MBeanServer类
MBean服务器是javax.management.MBeanServer接口的实例,要创建一个MBeanServer实例。只需要调用javax.management.MBeanServerFactory类的createMBean()方法即可。
要将一个MBean注册到MBean服务器中,可以调用MBeanServer实例的registerMBean()方法,下面是registerMBean方法的签名;
ObjectInstance registerMBean(java.lang.Object object, ObjectName var2) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException;
要调用registerMBean方法,需要传入一个待注册的MBean实例(就是第一个参数)和一个ObjectName实例,ObjectName实例与HashMap中的键类似,它可以唯一地标识一个MBean实例。registerMBean方法会返回一个ObjectInstance实例。javax.management.ObjectInstance类封装了一个MBean实例的对象名称和它的类名。
要想获取MBean实例或匹配某个模式的一组MBean实例。可以使用MBeanServer接口提供的两个方法,分别是queryNames方法 和 queryMBeans方法,queryNames方法返回一个java.util.Set实例,其中包含了匹配某个指定模式对象名称的一组MBean实例的对象名称,下面是queryNames方法的签名:
java.util.Set queryNames(ObjectName name, QueryExp query);
其中 query制定了过滤条件,若参数name为null 或者没有域,而且指定了key属性,name返回应注册的MBean实例的所有ObjectName实例,如果参数query为null,则不会对查找对象进行过滤。
queryMBeans方法与queryNames方法类似,它返回的也是一个java.util.Set实例,但是其中包含的是被选择的Mbean实例的ObjectInstance对象,queryMBean方法的签名如下:
java.util.Set queryMBeans(ObjectName name, QueryExp query);
一旦获得了所需要MBean实例对象名称,就可以操作托管资源在MBean实例中提供的属性或调用其方法,
可以通过调用MBeanServer接口的invoke方法调用已经注册的MBean实例的任何方法,MBeanServer接口的getAttribute方法 和 setAttribut方法用于获取或设置已经注册的MBean实例的属性。
ObjectName类
MBean实例注册于MBean服务器中,MBean服务器中的每一个MBean实例都通过一个对象名称来唯一标识,就好像是HashMap中的每一个条目都通过一个键来唯一的标识一样。
对象名称是javax.managerment.ObjectName类的实例,对象名称由两部分组成,域和一个键/值对。域是一个字符串,也可以是空字符串,在对象名称中,域后接一个分号,然后是一个或者多个键/值对,在键/值对重,键(key)是一个非空字符串,并且不能包含下列字符:等号、逗号、分号、星号、和问号。在一个对象名称中,同一个键只能出现一次,
键与其值是由等号分隔的,键/值对之间用逗号号分隔。例如下面是一个有效的对象名称,其中包含两个键:
myDomain:type=Car,color=blue
域:key=value,key = value
ObjetName实例也表示在MBean服务器中搜索MBean实例的属性模式,ObjectName实例可以在 域 部分或者 键值对 部分使用通配符来表示模式,作为模式的ObjectName可以有 0 个或多个键。
标准MBean
标准MBean是最简单的MBean类型,要想通过标准MBean来管理一个java对象,需要执行以下步骤。
- 创建一个接口,该接口的命名规范为:java类名+MBean后缀。例如,如果想要管理的java类名为Car,则需要创建的接口命名为CarMBean;
- 修改java类,让其实现刚刚创建的CarMBean接口。
- 创建一个代理,该代理类必须包含一个MbeanServer实例。
- 为Mbean创建ObjectName实例;
- 实例化MBeanServer类,
- 将MBean注册到MBeanServer中;
标准MBean是最容易编写的MBean类型,但是用标准MBean就必须要修改原有的java类,在某些项目中,这不是问题,但是在其他一些项目(尤其是很多类的项目)中,这是不可以接受的,其他类型的MBean允许在不修改原有java类的基础上管理java对象,
下面是一个标准MBean的例子,其中假设你想要使其成为JMC可管理的类是Car,
第一步 先创建一个符合命名规范的接口
1 package myex20.pyrmont.Standardmbeantest; 2 3 /** 4 * <p> 5 * <b>Title:CarMBean.java</b> 6 * </p> 7 * <p> 8 * Copyright:ChenDong 2018 9 * </p> 10 * <p> 11 * Company:仅学习时使用 12 * </p> 13 * <p> 14 * 类功能描述:要管理Car类的标准MBean接口 15 * 创建一个接口,该接口的命名规范为:java类名+MBean后缀。例如,如果想要管理的java类名为Car,则需要创建的接口命名为CarMBean; 16 * </p> 17 * <p> 18 * 基本上来讲,要在接口中声明Car类中的所要提供的所有方法,在这个例子中,在CarMBean接口中生命了Car类的所有方法,如果不希望Car类的drive方法在管理应用程序中调用, 19 * 只需要将drive方法的定义从CarMBean中移除即可。 20 * </p> 21 * 22 * @author 陈东 23 * @date 2018年12月4日 下午7:36:50 24 * @version 1.0 25 */ 26 public interface CarMBean { 27 public String getColor(); 28 29 public void setColor(String color); 30 31 public void drive(); 32 33 }
然后让我们想要被管理的原java类 也就是 Car类实现该接口
1 package myex20.pyrmont.Standardmbeantest; 2 3 /** 4 * <p> 5 * <b>Title:Car.java</b> 6 * </p> 7 * <p> 8 * Copyright:ChenDong 2018 9 * </p> 10 * <p> 11 * Company:仅学习时使用 12 * </p> 13 * <p> 14 * 类功能描述: 15 * </p> 16 * 17 * @author 陈东 18 * @date 2018年12月4日 下午7:34:25 19 * @version 1.0 20 */ 21 public class Car implements CarMBean { 22 private String color = "red"; 23 24 public String getColor() { 25 return color; 26 } 27 28 public void setColor(String color) { 29 this.color = color; 30 } 31 32 public void drive() { 33 System.out.println("Baby you can drive my*" + color + "*car."); 34 } 35 }
然后创建一个代理类 包含一个 MBeanServer类的实例 来管理 Mbean
1 package myex20.pyrmont.Standardmbeantest; 2 3 import javax.management.Attribute; 4 import javax.management.AttributeNotFoundException; 5 import javax.management.InstanceAlreadyExistsException; 6 import javax.management.InstanceNotFoundException; 7 import javax.management.InvalidAttributeValueException; 8 import javax.management.MBeanException; 9 import javax.management.MBeanRegistrationException; 10 import javax.management.MBeanServer; 11 import javax.management.MBeanServerFactory; 12 import javax.management.NotCompliantMBeanException; 13 import javax.management.ObjectName; 14 import javax.management.ReflectionException; 15 16 /** 17 * <p> 18 * <b>Title:StandardAgent.java</b> 19 * </p> 20 * <p> 21 * Copyright:ChenDong 2018 22 * </p> 23 * <p> 24 * Company:仅学习时使用 25 * </p> 26 * <p> 27 * 类功能描述: 代理类用来实例化MBean服务器,并使用MBean服务器注册CarBean实例。首先要注意的是变量 28 * MBeanServer,StandardAgent类的构造函数会将一个MBeanServer实例赋值给变量MBeanServer。 29 * 构造函数会调用MBeanServerFactory类的createMBeanServer方法 创建一个MBeanServer实例, 30 * createMBeanServer方法 31 * 会返回JMX参考实现的一个默认的MBeanServer对象。资深JMX程序员可能会实现自己的MBeanServer, 32 * </p> 33 * * @author 陈东 34 * 35 * @date 2018年12月4日 下午7:44:13 36 * @version 1.0 37 */ 38 public class StandardAgent { 39 /** 40 * 管理MBean的服务器实例 41 */ 42 private MBeanServer mBeanServer = null; 43 44 /** 45 * 46 * 47 * <p> 48 * Title:无参数构造器 49 * </p> 50 * 51 * <p> 52 * Description: 使用默认构造创建一个新的{@code StandardAgent }实例 53 * </p> 54 */ 55 public StandardAgent() { 56 // 使用MBeanServerFactory工程类 创建MBeanServer实例 57 mBeanServer = MBeanServerFactory.createMBeanServer(); 58 } 59 60 /** 61 * 62 * 63 * <p> 64 * Title: getMBeanServer 65 * </p> 66 * 67 * @date 2018年12月4日 下午7:51:31 68 * 69 * <p> 70 * 功能描述: 获取代理类中的MBeanServer实例 71 * </p> 72 * 73 * @return 74 */ 75 public MBeanServer getMBeanServer() { 76 return mBeanServer; 77 } 78 79 /** 80 * 81 * 82 * <p> 83 * Title: createObjectName 84 * </p> 85 * 86 * @date 2018年12月4日 下午7:55:07 87 * 88 * <p> 89 * 功能描述: 根据指定的name属性来创建 {@code ObjectName} 实例 90 * </p> 91 * 92 * @param name 93 * @return 94 */ 95 public ObjectName createObjectName(String name) { 96 ObjectName objectName = null; 97 try { 98 objectName = new ObjectName(name); 99 } catch (Exception e) { 100 e.printStackTrace(); 101 } 102 return objectName; 103 104 } 105 106 /** 107 * 108 * 109 * <p> 110 * Title: createStandardBean 111 * </p> 112 * 113 * @date 2018年12月4日 下午8:09:01 114 * <p> 115 * 功能描述: 方法中会调用MBeanServer实例的createMBean方法,createMBean方法接收托管资源的类名, 116 * 和一个ObjectName实例,该ObjectName实例 117 * 唯一的表示了为托管资源创建的MBean实例,creatMBean方法也会将创建的MBean实例注册到MBean 118 * 服务器中。由于标准MBean实例遵循了特定的命名规则,因此不需要 119 * 为createMbean方法提供MBean的类名,如果托管资源的类名是Car,则创建的MBean的类名为CarMBean。 120 * </p> 121 * 122 * 123 * @param objectName 124 * @param managedResourceClassName 125 */ 126 @SuppressWarnings("unused") 127 private void createStandardBean(ObjectName objectName, String managedResourceClassName) { 128 try { 129 mBeanServer.createMBean(managedResourceClassName, objectName); 130 } catch (InstanceAlreadyExistsException e) { 131 // TODO Auto-generated catch block 132 e.printStackTrace(); 133 } catch (NotCompliantMBeanException e) { 134 // TODO Auto-generated catch block 135 e.printStackTrace(); 136 } catch (MBeanRegistrationException e) { 137 // TODO Auto-generated catch block 138 e.printStackTrace(); 139 } catch (MBeanException e) { 140 // TODO Auto-generated catch block 141 e.printStackTrace(); 142 } catch (ReflectionException e) { 143 // TODO Auto-generated catch block 144 e.printStackTrace(); 145 } 146 147 } 148 149 public static void main(String[] args) { 150 // 创建一个代理类的实例 151 StandardAgent agent = new StandardAgent(); 152 // 获取一个MBeanServer 的引用 153 MBeanServer mBeanServer = agent.getMBeanServer(); 154 155 /** 156 * 为我们要管理的CarBean实例 157 * 创建一个ObjectName对象,MBeanServer实例的默认域会作为ObjectName实例的域使用。 158 * 一个名为type的键会被添加到域的后面,键type的值是托管资源的完全限定名; 159 */ 160 // 获取 MBeanServer实例的默认域 161 String domain = mBeanServer.getDefaultDomain(); 162 // 被托管资源java类的完全限定名 不是对应的MBean包装类 163 String managedResourceClassName = "myex20.pyrmont.Standardmbeantest.Car"; 164 // 然后创建ObjectName对象 165 ObjectName oname = agent.createObjectName(domain + ":type=" + managedResourceClassName); 166 // 调用 agent的 createStandardMBean方法,并传入创建好的 对象名称对象 和 托管资源java类的 类限定名 167 // 接着 就会调用MBeanServer的 creatMBean来创建并管理 168 // CarMBean,也就是通过CarMBean实例来管理Car对象。 169 agent.createStandardBean(oname, managedResourceClassName); 170 // 创建一个名为 colorattribute的Attribute类型的对象,用来表示Car类的color属性,并设置其值 为blue, 171 Attribute colorattribute = new Attribute("Color", "blue"); 172 // 然后 用MBean 服务器对象的setAttribute方法,传入代表 CarMBean 的ObjectName 对象 与 为 173 // CarBean管理的Car设置的Attitude对象 174 try { 175 mBeanServer.setAttribute(oname, colorattribute); 176 System.out.println(mBeanServer.getAttribute(oname, "Color")); 177 mBeanServer.invoke(oname, "drive", null, null); 178 } catch (InstanceNotFoundException | InvalidAttributeValueException | AttributeNotFoundException 179 | ReflectionException | MBeanException e) { 180 181 e.printStackTrace(); 182 } 183 184 } 185 186 }
剩余步骤大家看 上面代码吧 ,不想再写啦哈。
从上面的例子我们可以看到,我们已经可以通过StandardAgent类来直接访问Car对象了,但是这里的关键问题是可以选择那些功能要暴露出来,那些方法需要对外隐藏。
模型MBean
相对于标准MBean,模型MBean更具有灵活性,在编程上,模型MBean难度更大一些,但是也不需要为可管理的对象修改原java类了,如果不能修改已有的java类,那么使用模型MBean是一个不错的选择。
使用模型MBean与使用标准MBean有一些区别,在使用标准MBean来管理资源时,需要定义一个接口,然后让托管资源实现该接口,而使用模型MBean时,不需要定义接口,相反是可以使用javax.management.modelmbean.ModelMBean接口来表示模型MBean
,只需要实现该接口,在JMX的参考实现中,有一个javax.management.modelmbean.RequiredModelMBean类,是ModelMBean接口的默认实现,可以实例化RequiredModelMBean类或者其子类,也可以使用ModelMBean接口的其他实现类。
编写一个模型MBean的最大挑战是告诉ModelMBean对象托管资源的那些属性和方法可以暴露给代理,可以通过创建 javax.management,modelmbean.ModelMBeanInfo对象来完成这个任务,ModelMBeanInfo对象描述了将会暴露给代理的构造函数、属性、操作、甚至是监听器。创建ModelMBeanInfo对象是一件特别枯燥的事情,但当创建了该实例后,只需要将其与ModelMBean对象相关联即可。
使用RequiredModelMBean类作为ModelMBean的实现,有两种方式可以将ModelMBeanInfo对象相关联;
- 传入一个ModelMBeanInfo对象到 RequiredModelMBean对象的构造函数中
- 调用RequiredModelMBean类的setModelMBeanInfo方法,并传入一个ModelMBean对象
在创建了ModelMBean对象之后,需要调用ModelMbean接口的setManagedResource方法将 ModelMBean与其托管的资源相互关联,该方法的签名如下
public void setManagedResource(java.lang.Object managedResource, java.lang.String managedResourceType) throws MBeanException, RuntimeOperationsException, InstanceNotFoundException, InvalidTargetObjectTypeException ;
字符串参数 managedResourceType的值只可以是下面之一:ObjectReference、Handle、IOR、EJBHandle或者RMIReference。当前只支持ObjectReference。
还需要创建一个ObjectName实例,并将MBean实例注册到MBean服务器中,下面先介绍一下ModelMBeanInfo接口,该接口的实例会将托管资源的属性 和方法提供给代理层。
MBeanInfo 接口 与 ModelMBeanInfo接口
javax.management,mbean.ModelMBeanInfo接口描述了要通过ModelMBean暴露给代理层的构造函数、属性、方法、和监听器,其中 构造函数是 javax.management.modelmbean.ModelMBeanConstructorInfo类的实例,属性是javax.management.modelmbean.ModelMBeanAttributeInfo类的实例,方法是javax.management.modelmbean.ModelMBeanOperationInfo类的实例,监听器是 javax.management.modelmbean.ModelMBeanNotificationInfo类的实例,
JMX提供了ModelMBeanInfo接口的默认实现,即javax.management.modelmbean.ModelMBeanInfoSupport类。下面展示一下 我们后面要使用的ModelMBeanInfoSupport类的构造函数:
public ModelMBeanInfoSupport(String className, String description, ModelMBeanAttributeInfo[] attributes, ModelMBeanConstructorInfo[] constructors, ModelMBeanOperationInfo[] operations, ModelMBeanNotificationInfo[] notifications) { this(className, description, attributes, constructors, operations, notifications, null); }
可以通过调用ModelMBeanAttributeInfo类的构造函数来创建ModelMBeanAttributeInfo对象:
public ModelMBeanAttributeInfo(String name, String type, String description, boolean isReadable, boolean isWritable, boolean isIs, Descriptor descriptor)
下面是参数列表:
- name:属性的名称
- type,属性的类型名
- description:对属性的描述
- isReadable:,true表示针对该属性有一个getter方法,false表示没有
- isWriteable:true 表示针对该属性有一个 setter方法,false表示没有
- isIs,true 表示针对该属性有一个getter方法 ,false表示没有
- descriptor:Descriptor类的实例,包含Attribute的适当元数据,如果它为null,会创建默认的Descriptor实例。
可以使用下面的构造函数创建一个 ModelMBeanOperationInfo对象
public ModelMBeanOperationInfo(String name, String description, MBeanParameterInfo[] signature, String type, int impact, Descriptor descriptor)
下面是参数列表;
- name:方法名
- description :方法描述
- signature:MBeanParameterInfo对象的数组,描述了方法的参数
- type:方法的返回值类型
- impact:方法的影响 是一个整型变量 ,为了方便大家的使用 使用了javax.management.MBeanOperationInfo类中的几种常量来表示
-
/** * 方法返回信息但不改变任何状态 */ public static final int INFO = 0;
-
/** * 指示该操作是写式的:它具有效果,但不从MBean返回任何信息 */ public static final int ACTION = 1;
-
/** *指示该操作既读又写:它具有效果,并且还返回来自MBean的信息 */ public static final int ACTION_INFO = 2;
-
/** * 指示操作的影响是未知的,或者无法使用其他值之一来表示。 */ public static final int UNKNOWN = 3;
只可以选择上面的四种
- descriptor:Descriptor实例,包含MBeanOperationInfo实例的适当元数据
我们还是使用原来的Car类作为MBean的管理对象代码如下
package myex20.pyrmont.Standardmbeantest; /** * <p> * <b>Title:Car.java</b> * </p> * <p> * Copyright:ChenDong 2018 * </p> * <p> * Company:仅学习时使用 * </p> * <p> * 类功能描述: * </p> * * @author 陈东 * @date 2018年12月4日 下午7:34:25 * @version 1.0 */ public class Car { private String color = "red"; public String getColor() { return color; } public void setColor(String color) { this.color = color; } public void drive() { System.out.println("Baby you can drive my*" + color + "*car."); } }
对于模型MBean,不需要像使用标准MBean那样,编写一个接口,只需要实例化RequiredMBean类,下面展示一个ModelAgent类的定义,该类用来创建模型MBean实例,并管理Car对象。
1 package myex20.pyrmont.modelmbeantest1; 2 3 import javax.management.Attribute; 4 import javax.management.AttributeNotFoundException; 5 import javax.management.Descriptor; 6 import javax.management.InstanceNotFoundException; 7 import javax.management.InvalidAttributeValueException; 8 import javax.management.MBeanException; 9 import javax.management.MBeanInfo; 10 import javax.management.MBeanOperationInfo; 11 import javax.management.MBeanParameterInfo; 12 import javax.management.MBeanServer; 13 import javax.management.MBeanServerFactory; 14 import javax.management.MalformedObjectNameException; 15 import javax.management.ObjectName; 16 import javax.management.ReflectionException; 17 import javax.management.RuntimeOperationsException; 18 import javax.management.modelmbean.DescriptorSupport; 19 import javax.management.modelmbean.InvalidTargetObjectTypeException; 20 import javax.management.modelmbean.ModelMBean; 21 import javax.management.modelmbean.ModelMBeanAttributeInfo; 22 import javax.management.modelmbean.ModelMBeanInfo; 23 import javax.management.modelmbean.ModelMBeanInfoSupport; 24 import javax.management.modelmbean.ModelMBeanOperationInfo; 25 import javax.management.modelmbean.RequiredModelMBean; 26 27 /** 28 * <p> 29 * <b>Title:ModelAgent.java</b> 30 * </p> 31 * <p> 32 * Copyright:ChenDong 2018 33 * </p> 34 * <p> 35 * Company:仅学习时使用 36 * </p> 37 * <p> 38 * 类功能描述:用于创建模型MBean的实例,在该类中用其JMX参考中的默认实现RequiredModelMBean,并管理Car 39 * 并包含一个MBeanServer实例 40 * 41 * </p> 42 * <p> 43 * 请访问下面网址 进行 参考学习 {@see https://www.cnblogs.com/ChenD/p/10061598.html} 44 * </p> 45 * 46 * @author 陈东 47 * @date 2018年12月5日 下午9:24:36 48 * @version 1.0 49 */ 50 public class ModelAgent { 51 /** 52 * 管理的Car类的完全限定名 53 */ 54 private String MANAGED_CLASS_NAME = "myex20.pyrmont.modelmbeantest1.Car"; 55 56 /** 57 * 用于管理MBean的MBeanServer实例 58 */ 59 private MBeanServer mBServer = null; 60 61 public ModelAgent() { 62 mBServer = MBeanServerFactory.createMBeanServer(); 63 } 64 65 public MBeanServer getMBeanServer() { 66 return mBServer; 67 } 68 69 /** 70 * 71 * 72 * <p> 73 * Title: createObjectName 74 * </p> 75 * 76 * @date 2018年12月5日 下午9:39:47 77 * 78 * <p> 79 * 功能描述:用指定的name创建ObjectName对象 80 * </p> 81 * 82 * @param name 83 * @return 84 */ 85 private ObjectName createObjectName(String name) { 86 ObjectName obj = null; 87 88 try { 89 obj = new ObjectName(name); 90 } catch (MalformedObjectNameException e) { 91 92 e.printStackTrace(); 93 } 94 return obj; 95 96 } 97 98 /** 99 * 100 * 101 * <p> 102 * Title: createMBean 103 * </p> 104 * 105 * @date 2018年12月6日 下午9:39:09 106 * 107 * <p> 108 * 功能描述:创建 ModelMBean 109 * </p> 110 * 111 * @param objectName 112 * @param mbeanName 113 * @return 114 */ 115 private ModelMBean createMBean(ObjectName objectName, String mbeanName) { 116 // ModelMBeanInfo接口描述了要通过ModelMBean暴露给代理层的构造函数、属性、方法、和监听器 117 // 先创建一个描述 要创建的ModelMBean类 要暴露给代理层的 各种 信息 118 ModelMBeanInfo mBeanInfo = createModelMBeanInfo(objectName, mbeanName); 119 RequiredModelMBean modelMBean = null; 120 try { 121 modelMBean = new RequiredModelMBean(mBeanInfo); 122 } catch (Exception e) { 123 e.printStackTrace(); 124 } 125 return modelMBean; 126 } 127 128 /** 129 * 130 * 131 * <p> 132 * Title: createModelMBeanInfo 133 * </p> 134 * 135 * @date 2018年12月5日 下午10:03:03 136 * 137 * <p> 138 * 功能描述:为ModelMBean 类创建类信息 ModelMBeanInfo 139 * 140 * </p> 141 * <p> 142 * 对象 ModelMBeanInfo对象的几个子接口 构造函数是 143 * javax.management.modelmbean.ModelMBeanConstructorInfo类的实例, 144 * 属性是javax. 145 * management.modelmbean.ModelMBeanAttributeInfo类的实例,方法是javax. 146 * management.modelmbean.ModelMBeanOperationInfo类的实例,监听器是 147 * javax.management.modelmbean.ModelMBeanNotificationInfo类的实例, 148 * </p> 149 * 150 * @param inMBeanObjectName 151 * @param inMBeanName 152 * @return 153 */ 154 private ModelMBeanInfo createModelMBeanInfo(ObjectName inMBeanObjectName, String inMBeanName) { 155 156 // ModelMBean类的 类信息接口 157 ModelMBeanInfo mBeaninfo = null; 158 // ModelMBean类的 属性 对象集合 159 ModelMBeanAttributeInfo[] attributes = new ModelMBeanAttributeInfo[1]; 160 // ModelMBean类的 方法 对象集合 161 ModelMBeanOperationInfo[] operations = new ModelMBeanOperationInfo[3]; 162 try { 163 164 // 属性名:Color,类型:java.lang.String 描述信息:the Color。 isReadable:true 165 // 有getter方法,isWriteable:true 有setter方法 166 // isIS :false 无getter方法,descriptor :无 167 attributes[0] = new ModelMBeanAttributeInfo("Color", "java.lang.String", "the Color.", true, true, false, 168 null); 169 /** 170 * 第三个参数为 该方法的参数数组 null代表无参数, 171 */ 172 operations[0] = new ModelMBeanOperationInfo("drive", "the drive method", null, "void", 173 MBeanOperationInfo.ACTION, null); 174 /** 175 * Car的getColor方法 176 * 177 */ 178 operations[1] = new ModelMBeanOperationInfo("getColor", "get color attribute", null, "java.lang.String", 179 MBeanOperationInfo.ACTION, null); 180 181 // setColor方法 182 String fileds[] = new String[] { "name=setColor", "descriptorType=operation", "class=" + MANAGED_CLASS_NAME, 183 "role=operation" }; 184 Descriptor setColorDesc = new DescriptorSupport(fileds); 185 /** 186 * MBeanOperationInfo 描述方法的参数对象 187 */ 188 MBeanParameterInfo[] setColorParams = new MBeanParameterInfo[] { 189 new MBeanParameterInfo("new color", "java.lang.String", "new Color value") }; 190 /** 191 * name:方法名 description :方法描述 192 * signature:MBeanParameterInfo对象的数组,描述了方法的参数 type:方法的返回值类型 193 * impact:方法的影响 是一个整型变量 ,为了方便大家的使用 194 * 使用了javax.management.MBeanOperationInfo类中的几种常量来表示 195 * ACTION:指示该操作是写式的:它具有效果,但不从MBean返回任何信息 196 */ 197 198 operations[2] = new ModelMBeanOperationInfo("setColor", "set color attribute", setColorParams, "void", 199 MBeanOperationInfo.ACTION, setColorDesc); 200 201 mBeaninfo = new ModelMBeanInfoSupport(MANAGED_CLASS_NAME, null, attributes, null, operations, null); 202 203 } catch (Exception e) { 204 e.printStackTrace(); 205 } 206 return mBeaninfo; 207 208 } 209 210 public static void main(String[] args) { 211 212 ModelAgent agent = new ModelAgent(); 213 MBeanServer server = agent.getMBeanServer(); 214 Car car = new Car(); 215 // 获取 MBeanServer实例的默认域 216 String domain = server.getDefaultDomain(); 217 ObjectName objectName = agent.createObjectName((domain + ":type=MyCar")); 218 String mbeanName = "myMBean"; 219 ModelMBean bean = agent.createMBean(objectName, mbeanName); 220 // 在创建了ModelMBean对象之后,需要调用ModelMbean接口的setManagedResource方法将 221 // ModelMBean与其托管的资源相互关联, 222 // public void setManagedResource(java.lang.Object managedResource, 223 // java.lang.String managedResourceType) throws MBeanException, 224 // RuntimeOperationsException, InstanceNotFoundException, 225 // InvalidTargetObjectTypeException ; 226 // managedResourceType 目前只支持 ObjectReference 227 try { 228 bean.setManagedResource(car, "ObjectReference"); 229 // 将与托管资源关联好的ModelMBean 注册到 MBean服务器中 230 server.registerMBean(bean, objectName); 231 232 } catch (Exception e) { 233 // TODO Auto-generated catch block 234 e.printStackTrace(); 235 } 236 // 管理代理类 237 238 try { 239 Attribute attribute = new Attribute("Color", "green"); 240 server.setAttribute(objectName, attribute); 241 String color = (String) server.getAttribute(objectName, "Color"); 242 System.out.println("Color:" + color); 243 244 attribute = new Attribute("Color", "blue"); 245 server.setAttribute(objectName, attribute); 246 color = (String) server.getAttribute(objectName, "Color"); 247 System.out.println("Color:" + color); 248 249 251 server.invoke(objectName, "drive", null, null); 252 server.invoke(objectName, "setColor", new String[]{"blue"},new String[]{"java.lang.String"}); 253 server.invoke(objectName, "drive", null, null); 254 255 } catch (Exception e) { 256 // TODO Auto-generated catch block 257 e.printStackTrace(); 258 } 259 260 } 261 262 }
在执行main之后 的运行结果
Color:green Color:blue Baby you can drive my*red*car. Baby you can drive my*blue*car.
因为在使用MBeanServer类的invoke时 看下方法签名吧 我一次传带参数的值 就传错了 记录下
public Object invoke(ObjectName name, String operationName, Object params[], String signature[]) throws InstanceNotFoundException, MBeanException, ReflectionException;
- name: 注册时 用的ObjectName对象
- operationName:要调用的方法名
- params:代表参数数组 定义成Object 是为了可以满足任何类型的参数 ,按照参数顺序依次 定义数组内容
- signature:也是一个数组 代表 参数 元素的 类型 例如 参数是String 那么它的类型 就是 java.lang.String
从上面的例子我们已经看出来了 最麻烦的就是创建ModelMBeanInfo信息了,如果这个步骤不可以简化 那么这个ModelMBean将不具备可用性,
那么为了简化创建ModelMBeanInfo信息引入了一个Commons Modeler 库
Commons Modeler
Commons Modeler 库是Apache软件基金会的Jakarta项目的一部分,目的就是使编写模型MBean更加方便,事实上最大的帮助是不需要向上面一样写创建ModelMBeanInfo对象的代码了。
回忆下之前的例子,在创建RequiredModelMBean实例时,需要创建一个ModelMBeanInfo对象,并将其传给RequiredModelMBean类的构造函数:
ModelMBeanInfo mBeanInfo = createModelMBeanInfo(objectName, mbeanName); RequiredModelMBean modelMBean = null; try { modelMBean = new RequiredModelMBean(mBeanInfo); } catch (Exception e) { e.printStackTrace(); }
ModelMbeanInfo对象描述了将要由MBean实例暴露出来的属性和方法,实现createModelMBeanInfo方法是特别枯燥的而且麻烦死了,因为必须列出所有要暴露出来的属性和方法 并将它们传给ModelMBeanInfo对象。
而使用Commons Modeler库,就不在需要创建ModelMBeanInfo对象了,相反对模型MBean的描述被封装在一个 org.apache.catalina.modeler.ManagedBean对象中。不需要编写代码在MBean中暴露出属性和方法。只需要编写一个mbean描述文件(一个XML文档),列出想要创建的MBean,对于每个MBean,需要写出MBean类和托管资源类的完全限定名,此外还有由MBean暴露出来的属性和方法,然后使用org.apache.commons.modeler.Registry实例来读取这个XML文档,并创建一个MBeanServer实例,在按照mbean描述文件中的XML元素创建所有的ManagedBean实例。
然后调用ManagedBean实例的createMBean方法创建模型MBean,这之后就是普通的流程了,需要创建ObjectName对象的实例,并将其与MBean实例一起注册到MBean服务器中,下面会先介绍一下mbean描述文件的格式,然后讨论Modeler库中的三个重要的类,分别是Registry类,ManagedBean类、和BaseModelMBean类。
注意:为了更好的理解Modeler库,org.apache.catalina.mbeans包中与MBean相关类的工作原理 。我们仍然使用老版本,
MBean描述符
MBean描述符是一个XML 文档,该文档描述了将会由Mbean服务器管理的 ModelMBean的实例,MBean描述符以下面的头信息开始:
<?xml version="1.0"?> <!DOCTYPE mbeans-descriptors PUBLIC "-//Apache Software Foundation//DTD Model MBeans Configuration File" "http://jakarta.apache.org/commons/dtds/mbeans-descriptors.dtd">
接下来是mbeans-descriptors的根元素
<mbeans-descriptors> ... </mbeans-descriptors>
在开始和末尾的mbeans-descriptors标签内部是mbean元素,每一个mbean元素标签表示一个模型MBean,mbean元素包含了分别用来表示属性、方法、构造函数、和通知的元素。
mbean元素
mbean元素描述了一个模型MBean,包含创建对应ModelMBeanInfo对象的信息。mbean元素的定义如下所示:
<!ELEMENT mbean(descriptor?,attribute*,constructor*,notification*,operation*)>
mbean元素定义了具体的规范,mbean元素可以有一个可选的descriptor元素,0个或者多个attribute元素。0个或者多个constructor元素,0个或者多个notification元素。0个或者多个operation元素。
mbean元素可以有如下的属性:
- className :实现ModelMBean接口的java类的完全限定名,若该属性未赋值,则默认使用org.apache.commons.modeler.BaseModelMBean类;
- description: 该ModelMBean类的简单描述
- domain:在创建ModelMBean的ObjectName对象时,托管的bean 的 ModelMBean实例被注册到MBeanServer的域名。
- group: 组分类的可选名,可以用来选择具有相似MBean实例类的组;
- name:唯一标识模型MBean的名称,一般情况下,会使用相关服务器组件的基类名。
- type:托管资源实现类的完全限定java类名。
attribute 元素
使用attribute元素描述MBean的javaBean属性。attribute元素有一个可选的descripotr元素,attribute元素可以由如下的属性:
- description:该属性的简单描述
- displayName:该属性的显示名称;
- getMethod:返回 attribute元素 的getter方法;
- is:一个布尔值,指明该属性是否是一个布尔值,是否有getter方法,默认情况下,该属性值为false;
- name:该javaBean属性的名称:
- readable:一个布尔值,指明该属性对管理应用程序来说是否可读,该属性默认值为 true;
- setMethod,设置 attribute属性的setter方法;
- type:该属性的完全限定java类名;
- writeable:一个布尔值。指明该属性对管理应用程序来说是否可写,该属性的默认值为true;
operation 元素
operation元素描述了模型MBean 中要暴露给管理应用程序的公共方法,它可以有.个或者多个parameter子元素和如下的属性:
- description:方法的简单描述
- impact:指明方法的影响,可选值,ACTION、ACTION-INFO、INFO或UNKNOWN;值的意思参考 ModelMBeanOperationInfo对象 的讲述;
- name:公共方法的名称;
- returnType:方法返回值的完全限定的java类名。
parameter 元素
parameter元素描述了将要传递给构造函数 或者 方法的参数,它可以有如下的属性:
- description:该参数的简单描述
- name:参数名
- type:该参数完全限定的java类名
mbean元素的示例
在Catalin的 mbean-descriptors.xml文件中声明了一系列模型MBean,该文件位于org.apache.catalina.mbean 包下,下面给出了 mbean-descriptors.xml文件中对于StandardServer MBean的声明
<mbean name="StandardServer" className="org.apache.catalina.mbeans.StandardServerMBean" description="Standard Server Component" domain="Catalina" group="Server" type="org.apache.catalina.core.StandardServer"> <attribute name="debug" description="The debugging detail level fot this component" type="int"/> <attribute name="managedResource" description="The managed resource this MBean is asscoiated with" type="java.lang.Object"/> <attribute name="port" description="TCP port for shutdown messages" type="int"/> <attribute name="shutdown" description="Shutdown password" type="java.lang.String"/> <operation name="store" description="Save current state to server.xml file" impact="ACTION" returnType="void"> </operation> </mbean>
上述代码中的mbean元素声明了一个模型MBean,其唯一标识是StandardServer,该MBean是org.apache.catalina.mbeans.StandardServerMBean类的一个对象,负责管理org.apache.catalina.core.StandardServer类的对象。
domain属性的值是 Catalina,group的属性是Server。
模型MBean暴露出的属性有四个,分别是debug、managedResource、port和shutdown。正如mbean元素中嵌套的四个attribute元素所描述的一样,此外,Mbean还暴露出了一个方法,即 store方法,由 operation元素描述。
自己编写一个模型MBean类
使用Commons Modeler库,需要在mbean元素的className属性中指明自定义的模型MBean的类型,默认情况下,Commons Modeler库使用 org.apache.commons.modeler.BaseModelMBean类。
有以下两种情况。其中可能需要对BaseModelMBean类进行扩展:
- 需要覆盖托管资源的属性或方法
- 需要添加在托管资源中没有定义的属性或方法
在org.apahce.catalina.mbeans包下,Catalina 提供了BaseModelMBean类的很多子类,可以用来实现上面的需求。
Registry类.
org.apahce.commons.modeler.Registry类定义了很多方法,下面是可以使用该类做的事情。
- 获取 javax.managedment.MBeanServer类的一个实例,所以不需要在调用javax.managedment.MbeanServerFactory类的createMBeanServer方法了
- 使用 loadRegistry方法获取MBean的描述文件
- 创建一个ManagedBean对象,用于创建模型MBean的实例。
ManagedMBean
ManagedMBean对象描述了一个模型MBean,该类用于取代javax.managedment.MBeanInfo对象。
BaseModelMBean
org.apache.commons.modeler.BaseModelMbean类实现了 javax.managedment.modelmbean.ModelMBean接口,使用这个类,就不需要使用javax.managedment.modelmbean.RequiredMoldeMBean这个类了,
该类用一个比较有用的字段是resource字段。resource字段表示该模型MBean管理的资源。resource字段的定义如下;
protected java.lang.Object resource = null;
使用Modeler库 API
下面代码给出了想要管理器对象Car类的定义
1 package myex20.pyrmont.modelmbeantest2; 2 3 /** 4 * <p> 5 * <b>Title:Car.java</b> 6 * </p> 7 * <p> 8 * Copyright:ChenDong 2018 9 * </p> 10 * <p> 11 * Company:仅学习时使用 12 * </p> 13 * <p> 14 * 类功能描述:modelmbeantest2 中 要被管理的对象 15 * </p> 16 * 17 * @author 陈东 18 * @date 2018年12月10日 下午10:20:53 19 * @version 1.0 20 */ 21 public class Car { 22 public Car() { 23 System.out.println("Car constructor"); 24 } 25 26 private String color = "red"; 27 28 public String getColor() { 29 30 return this.color; 31 } 32 33 public void setColor(String color) { 34 this.color = color; 35 } 36 37 public void drive() { 38 System.out.println("Baby you can drive my " + color + " Car"); 39 } 40 41 }
使用Commons Modeler 库,不需要使用硬编码的方式,将托管对象的所有属性和方法都写在代码中,相反,可以将他们写在一个xml文件中,作为MBean的描述符文件,在这个例子当中,这样的文档是car-mbean-descriptor.xml文件,如下面所所示
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mbeans-descriptors PUBLIC "-//Apache Software Foundation//DTD Model MBeans Configuration File" "http://jakarta.apache.org/commons/dtds/mbeans-descriptors.dtd"> <mbeans-descriptors> <mbean name="myMBean" className="javax.management.modelmbean.RequiredModelMBean" description="The ModelMBean that manages our Car object" type="ex20.pyrmont.modelmbeantest.Car"> <attribute name="Color" description="The car color" type="java.lang.String"/> <operation name="drive" description="drive method" impact="ACTION" returnType="void"> <parameter name="driver" description="the driver parameter" type="java.lang.String"/> </operation> </mbean> </mbeans-descriptors>
那么我们写完这个描述文件之后,就需要一个在写一个代理类ModelAgent.java,具体看下面哈
package myex20.pyrmont.modelmbeantest2; import java.io.IOException; import java.io.InputStream; import java.net.URL; import javax.management.Attribute; import javax.management.MBeanServer; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.management.modelmbean.ModelMBean; import org.apache.commons.modeler.ManagedBean; import org.apache.commons.modeler.Registry; /** * <p> * <b>Title:ModelAgent.java</b> * </p> * <p> * Copyright:ChenDong 2018 * </p> * <p> * Company:仅学习时使用 * </p> * <p> * 类功能描述: modelmbeantest2包下的代理类 * </p> * * @author 陈东 * @date 2018年12月11日 下午7:43:28 * @version 1.0 */ public class ModelAgent { /** * <p> * 作用1:获取 {@link javax.management.MBeanServer } * </p> * * <p> * 作用2:使用loadRegistry方法来读取mbean描述文件; * </p> * * <p> * 作用3:创建一个@ * {@link org.apache.commons.modeler.ManagedBean}用于创建一个{@code ModelMBean} * </p> */ private Registry registry; private MBeanServer mbeanServer; public ModelAgent() { registry = createRegistry(); mbeanServer = Registry.getServer(); } public MBeanServer getMBeanServer() { return mbeanServer; } /** * * * <p> * Title: createRegistrt * </p> * * @date 2018年12月11日 下午8:28:44 * * <p> * 功能描述:创建Registry, * </p> * * @return */ private Registry createRegistry() { Registry registry = null; try { URL url = ModelAgent.class.getResource("/myex20/pyrmont/modelmbeantest2/car-mbean-descriptor.xml"); InputStream io = url.openStream(); Registry.loadRegistry(io); registry = Registry.getRegistry(); } catch (Exception e) { e.printStackTrace(); } return registry; } /** * * * <p> * Title: createModleMBean * </p> * <p> * 功能描述:用于创建指定名字的 ModelMBean 这里的名字必须是 mbean描述文件中的 mbean 元素的name属性所指定的才可以 * 否则返回null * </p> * * @date 2018年12月11日 下午8:46:54 * * * * @param mbeanName * @return * @throws Exception */ private ModelMBean createModleMBean(String mbeanName) throws Exception { // 根据指定的名字去找mbean描述文件中对应的配置所代表的 ManagedBean对象 ManagedBean managed = registry.findManagedBean(mbeanName); if (managed == null) { System.out.println("ManagedBean is null"); return null; } // 创建ModelMBean ModelMBean mbean = managed.createMBean(); return mbean; } /** * * * <p> * Title: createObjectName * </p> * * @date 2018年12月11日 下午8:45:25 * * <p> * 功能描述:创建用于向mbean服务器注册时为MBean做唯一标识 的ObjectName * </p> * * @return */ private ObjectName createObjectName() { ObjectName objectname = null; String domain = mbeanServer.getDefaultDomain(); try { objectname = new ObjectName(domain + ":type=MyCar"); } catch (MalformedObjectNameException e) { e.printStackTrace(); } return objectname; } public static void main(String[] args) { // 实例化代理类 ModelAgent agent = new ModelAgent(); // 使用代理类 获取MBeanServer MBeanServer server = agent.getMBeanServer(); // 要被托管的资源 Car car = new Car(); // 创建ObjectName ObjectName objectName = agent.createObjectName(); try { // 创建ModelMBean对象 名字必须在mbean 描述文件中有对应mbean元素 ModelMBean modelMBean = agent.createModleMBean("myMBean"); // 将托管资源 与 modelMBean对象关联起来 /** * 在创建了ModelMBean对象之后,需要调用ModelMbean接口的setManagedResource方法将 * ModelMBean与其托管的资源相互关联, public void * setManagedResource(java.lang.Object managedResource, * java.lang.String managedResourceType) throws MBeanException, * RuntimeOperationsException, InstanceNotFoundException, * InvalidTargetObjectTypeException ; managedResourceType 目前只支持 * ObjectReference */ modelMBean.setManagedResource(car, "ObjectReference"); // 将modelMBean 注册到 mbeanServer server.registerMBean(modelMBean, objectName); } catch (Exception e) { e.printStackTrace(); } // 管理这个托管资源 try { Attribute attribute = new Attribute("Color", "green"); server.setAttribute(objectName, attribute); String color = (String) server.getAttribute(objectName, "Color"); System.out.println("mbeanserver getAttribute Color:" + color); System.out.println("Car's Color:" + car.getColor()); attribute = new Attribute("Color", "blue"); server.setAttribute(objectName, attribute); color = (String) server.getAttribute(objectName, "Color"); System.out.println("mbeanserver getAttribute Color:" + color); System.out.println("Car's Color:" + car.getColor()); server.invoke(objectName, "drive", null, null); } catch (Exception e) { e.printStackTrace(); } } }
运行main方法后的结果
十二月 11, 2018 9:41:28 下午 org.apache.commons.modeler.Registry loadRegistry 信息: Loading registry information 十二月 11, 2018 9:41:28 下午 org.apache.commons.modeler.Registry getRegistry 信息: Creating new Registry instance 十二月 11, 2018 9:41:28 下午 org.apache.commons.modeler.Registry getServer 信息: Creating MBeanServer 十二月 11, 2018 9:41:28 下午 org.apache.commons.modeler.Registry loadRegistry 信息: Loading registry information Car constructor mbeanserver getAttribute Color:green Car's Color:green mbeanserver getAttribute Color:blue Car's Color:blue Baby you can drive my blue Car
看下我们在使用了Commons Modeler库之后 减少了好多代码吧
Catalina中的MBean
Catalina 在 org.apache.catalina.mbeans包中提供了一系列的MBean类,这些MBean类都直接 或者间接的继承自 org.apahce.commons.modeler.BaseModelMBean类,下面会为大家展示一下 Tomcat 4 中 三个最重要的MBean类,分别是ClassNameMBean类,
StandardServerMBean类、和MBeanFactory类,还有一个重要的工具类 MBeanUtil类。
BaseModelMBean类
因为下面要讲解的类直接或者间接都会继承该类,所以有必要讲解下 该类的一些 重要的属性 以及方法
首先 有一个 java.lang.Object 类型名为 resource的变量 表示 托管资源的实例对象
protected Object resource = null;
还有一个重要的方法也就 将托管资源 和 该ModelMBean相关联的方法 setManagedResource(Object resource,String type),看下面的展示
/** * * * <p> * Title: setManagedResource * </p> * * @date 2018年12月11日 下午10:13:06 * * <p> * 功能描述: 将 指定的 托管资源 resource ,绑定到当前的ModelMBean中 * </p> * * @param resource 指定的托管资源 * @param type 指定type 目前只支持 {@code objectreference} * @throws InstanceNotFoundException * @throws InvalidTargetObjectTypeException 若 type 不为 {@code objectreference} 抛出错误 * @throws MBeanException * @throws RuntimeOperationsException 若 指定的托管资源resource是null 则抛出错误 */ public void setManagedResource(Object resource, String type) throws InstanceNotFoundException, InvalidTargetObjectTypeException, MBeanException, RuntimeOperationsException { if (resource == null) { throw new RuntimeOperationsException(new IllegalArgumentException("Managed resource is null"), "Managed resource is null"); } else if (!"objectreference".equalsIgnoreCase(type)) { throw new InvalidTargetObjectTypeException(type); } else { this.resource = resource; } }
ClassNameMBean
org.apahce.catalina.mbeans.ClassNameMBean类 继承自 org.apache.commons.modeler.BaseModelMBean类,它提供了一个属性className,用于表示托管资源的类名,详细的内容看下面
1 package org.apache.catalina.mbeans; 2 3 import javax.management.MBeanException; 4 import javax.management.RuntimeOperationsException; 5 import org.apache.commons.modeler.BaseModelMBean; 6 7 /** 8 * 9 * <p> 10 * <b>Title:ClassNameMBean.java</b> 11 * </p> 12 * <p> 13 * Copyright:ChenDong 2018 14 * </p> 15 * <p> 16 * Company:仅学习时使用 17 * </p> 18 * <p> 19 * 类功能描述:这个类创建一个名为className属性,该属性将托管对象的完全限定类名报告为其值。 20 * </p> 21 * 22 * @author 陈东 23 * @date 2018年12月11日 下午10:18:52 24 * @version 1.0 25 */ 26 public class ClassNameMBean extends BaseModelMBean { 27 28 // ---------------------------------------------------------- Constructors 29 30 /** 31 * 32 * 用默认的<code>ModelMBeanInfo</code>信息构造ModelMBean。 33 * 34 * @exception MBeanException 35 * 如果对象的初始化引发异常 36 * @exception RuntimeOperationsException 37 * 如果发生错误 38 */ 39 public ClassNameMBean() throws MBeanException, RuntimeOperationsException { 40 41 super(); 42 43 } 44 45 // ------------------------------------------------------------ Properties 46 47 /** 48 * 返回其托管资源类的完全限定名 49 */ 50 public String getClassName() { 51 52 return (this.resource.getClass().getName()); 53 54 } 55 56 }
ClassNameMBean类时BaseModelMBean类的子类,其属性className在托管资源中是不可见的,mbeans-descriptors.xml文件中的很多mbean元素使用该类作为其ModelMBean的类型。
StandardServerMBean类
StandardServerMBean类继承自 org.apache.commons.modeler.BaseModelMBean类,用于管理 org.apache.catalina.core.StandardServer类的实例,StandardServerMBean类是ModelMBean类的一个示例,它重写了托管资源的store方法,当管理应用程序调用store方法的时候,实际上会执行StandardServerMBean实例的store方法,而不是托管资源StandardServer对象的store方法,
1 package org.apache.catalina.mbeans; 2 3 4 import javax.management.InstanceNotFoundException; 5 import javax.management.MBeanException; 6 import javax.management.MBeanServer; 7 import javax.management.RuntimeOperationsException; 8 import org.apache.catalina.Server; 9 import org.apache.catalina.ServerFactory; 10 import org.apache.catalina.core.StandardServer; 11 import org.apache.commons.modeler.BaseModelMBean; 12 13 14 /** 15 * 16 * <p> 17 * <b>Title:StandardServerMBean.java</b> 18 * </p> 19 * <p> 20 * Copyright:ChenDong 2018 21 * </p> 22 * <p> 23 * Company:仅学习时使用 24 * </p> 25 * <p> 26 * 类功能描述: {@code org.apache.catalina.core.StandardServer} 组件的ModelMBean实现。 27 * </p> 28 * 29 * @author 陈东 30 * @date 2018年12月13日 下午7:36:09 31 * @version 1.0 32 */ 33 34 public class StandardServerMBean extends BaseModelMBean { 35 36 37 // ------------------------------------------------------- Static Variables 38 39 40 /** 41 * 应用程序的<code>MBeanServer</code> 组件 42 */ 43 private static MBeanServer mserver = MBeanUtils.createServer(); 44 45 46 // ----------------------------------------------------------- Constructors 47 48 49 /** 50 * 51 * 使用默认的<code>ModelMBeanInfo</code> 实现一个<code>ModelMBean</code> 52 * 53 * @exception MBeanException 54 * 如果对象的初始化器引发异常 55 * @exception RuntimeOperationsException 56 * 57 */ 58 public StandardServerMBean() throws MBeanException, RuntimeOperationsException { 59 60 super(); 61 62 } 63 64 65 // ------------------------------------------------------------- Attributes 66 67 68 // ------------------------------------------------------------- Operations 69 70 71 /** 72 * 73 * 将整个<code>Server</code>的配置信息写入{@code server.xml}配置文件。 74 * 75 * @exception InstanceNotFoundException 76 * 如果找不到托管资源对象 77 * @exception MBeanException 78 * 如果对象的初始化器抛出异常,或者不支持持久性 79 * @exception RuntimeOperationsException 80 * 如果持久性机制报告了异常 81 */ 82 public synchronized void store() throws InstanceNotFoundException, 83 MBeanException, RuntimeOperationsException { 84 85 Server server = ServerFactory.getServer(); 86 if (server instanceof StandardServer) { 87 try { 88 ((StandardServer) server).store(); 89 } catch (Exception e) { 90 throw new MBeanException(e, "Error updating conf/server.xml"); 91 } 92 } 93 94 } 95 96 97 }
StandardServerMBean 是一种模型MBean,继承自BaseModelMBean,并重写了托管资源(org.apache.catalina.core.StandardServer)的一个方法