標準MBean所暴露的屬性,操做,通知都是固定不變的,都固化在ClassNameMBean這個接口中,靈活度不足。java
動態Mbean所暴露的特性是運行時確立,靈活度足夠,但編碼困難,由於你須要編碼實現每個屬性,操做與通知。ide
模型Mbean也是一種動態Mbean,可以使你更快的編寫動態MBean.函數
模型MBean的封裝類RequiredModelMBean實現了ModelMBean接口,而ModelMBean接口繼承自DynamicMBean,因此說模型Mbean也是一種動態Mbean。測試
首先定義須要管理的資源:ui
- package guojje.jmx;
- import javax.management.NotificationBroadcasterSupport;
- public class HelloWordShadow extends NotificationBroadcasterSupport{
- private String name = "anranran";
- public HelloWordShadow(String name){
- this.name = name;
- }
- public String getName(){
- System.out.println("invoke getName method!!");
- return name;
- }
- public void setName(String name){
- System.out.println("invoke setName method!!");
- this.name = name;
- }
- public void Say(){
- System.out.println("hi~!!!");
- }
- }
測試類:this
- package guojje.jmx;
- public class Main {
- public static void main(String args[]) throws Exception {
- JMXServiceURL jUrl = new JMXServiceURL("iiop", "192.168.1.61", 9998,
- "/jndi/rmi://localhost:9999/guojje");
- MBeanServer ms = MBeanServerFactory.createMBeanServer();
- JMXConnectorServer cs = JMXConnectorServerFactory
- .newJMXConnectorServer(jUrl, null, ms);
- cs.start();
- System.out.println("jmx address:" + cs.getAddress());
- exeHelloWordShadow(ms);
- }
- private static void exeHelloWordShadow(MBeanServer ms) throws Exception {
- RequiredModelMBean rmm = new RequiredModelMBean();
- //add a property called 'name'
- ModelMBeanAttributeInfo nameAttr = new ModelMBeanAttributeInfo("name","java.lang.String",
- "pepole name",true, true, false,null);
- ModelMBeanInfo mmInfo = new ModelMBeanInfoSupport(RequiredModelMBean.class.toString(), "Jmx demo", new ModelMBeanAttributeInfo[]{nameAttr}, null, null, null);
- rmm.setModelMBeanInfo(mmInfo);
- //System.out.println(nameAttr.getDescriptor().getFieldValue("value"));//1
- rmm.setAttribute(new Attribute("name", "guojianjun"));
- System.out.println(rmm.getAttribute("name"));
- //System.out.println(nameAttr.getDescriptor().getFieldValue("value")); //2
- }
目前name與HelloWorkShadow尚未任何關係,去掉1,2兩行註釋,你會發現ModelMBeanAttributeInfo的描述子用來存儲了這個值(代碼中,ModelMBeanAttributeInfo的最後一個參數,我設了null,JDK會爲之建立一個默認的描述子)。
編碼
如何把對MBean的操做轉移動對HelloWordShadow的操做,以達到咱們管是資源的目的。
第一步爲ModelMBeanAttributeInfo對像添加get,set方法.
- private static void exeHelloWordShadow(MBeanServer ms) throws Exception {
- RequiredModelMBean rmm = new RequiredModelMBean();
- Method getMethod = HelloWordShadow.class.getMethod("getName",
- new Class[] {});
- Method setMethod = HelloWordShadow.class.getMethod("setName",
- new Class[] {String.class});
- //add a property called 'name'
- ModelMBeanAttributeInfo nameAttr = new ModelMBeanAttributeInfo("name",
- "pepole name",getMethod, setMethod,null);
- ModelMBeanInfo mmInfo = new ModelMBeanInfoSupport(RequiredModelMBean.class.toString(), "Jmx demo", new ModelMBeanAttributeInfo[]{nameAttr}, null, null, null);
- rmm.setModelMBeanInfo(mmInfo);
- rmm.setAttribute(new Attribute("name", "guojianjun"));
- System.out.println(rmm.getAttribute("name"));
- }
運行結果:xml
jmx address:service:jmx:iiop://192.168.1.61:9998/jndi/rmi://localhost:9999/guojje
guojianjun
發現並無起做用。剛纔說到ModelMBeanAttributeInfo用了默認的描述子,咱們不防給
添加一個描述子:
- private static void exeHelloWordShadow(MBeanServer ms) throws Exception {
- .....
- Descriptor nameDesc = new DescriptorSupport();
- nameDesc.setField("name", "Name");//must be setted
- nameDesc.setField("descriptorType", "attribute");//must be setted
- nameDesc.setField("displayName", "Name");
- nameDesc.setField("getMethod", "getName");
- nameDesc.setField("setMethod", "setName");
- //add a property called 'name'
- ModelMBeanAttributeInfo nameAttr = new ModelMBeanAttributeInfo("name",
- "pepole name",getMethod, setMethod,nameDesc);
- ModelMBeanInfo mmInfo = new ModelMBeanInfoSupport(null, "Jmx demo", new ModelMBeanAttributeInfo[]{nameAttr}, null, null, null);
- rmm.setModelMBeanInfo(mmInfo);
- rmm.setAttribute(new Attribute("name", "guojianjun"));
- System.out.println(rmm.getAttribute("name"));
- }
更糟糕,直接報錯:Operation setName not in ModelMBeanInfo。
但這也說明是用描述子設定set方法是正確的。這樣咱們須要在ModelMBeanInfo中聲明setName操做,getName同樣:
.....
- //add a property called 'name'
- ModelMBeanAttributeInfo nameAttr = new ModelMBeanAttributeInfo("name",
- "pepole name",getMethod, setMethod,nameDesc);
- //parameter is not necessary
- ModelMBeanOperationInfo getName = new ModelMBeanOperationInfo(//
- "getName", //
- "get name attribute", //
- null, //
- "java.lang.String", //
- MBeanOperationInfo.ACTION, //
- null//
- );
- MBeanParameterInfo mParam = new MBeanParameterInfo("name", "java.lang.String", "set name methord param");
- ModelMBeanOperationInfo setName = new ModelMBeanOperationInfo(//
- "setName", //
- "set name attribute", //
- new MBeanParameterInfo[]{mParam}, //
- null, //
- MBeanOperationInfo.ACTION, //
- null//
- );
- ModelMBeanInfo mmInfo = new ModelMBeanInfoSupport(null, "Jmx demo", new ModelMBeanAttributeInfo[]{nameAttr},
- null , new ModelMBeanOperationInfo[]{getName,setName}, null);
- rmm.setModelMBeanInfo(mmInfo);
- rmm.setAttribute(new Attribute("name", "guojianjun"));
- System.out.println(rmm.getAttribute("name"));
仍然報錯: managedResource for invoke setName is null
managedResource是什麼?就是咱們須要管理的對像資源,在這裏固然是HelloWordShadow對象,終於扯上關係了。那就構造一個HelloWordShadow對象:
- .....
- ModelMBeanInfo mmInfo = new ModelMBeanInfoSupport(RequiredModelMBean.class.toString(), "Jmx demo", new ModelMBeanAttributeInfo[]{nameAttr},
- null , new ModelMBeanOperationInfo[]{getName,setName}, null);
- rmm.setModelMBeanInfo(mmInfo);
- HelloWordShadow hw = new HelloWordShadow("miniName");
- rmm.setManagedResource(hw, "ObjectReference");
- rmm.setAttribute(new Attribute("name", "guojianjun"));
- System.out.println(rmm.getAttribute("name"));
運行輸出:
jmx address:service:jmx:iiop://192.168.1.61:9998/jndi/rmi://localhost:9999/guojje
invoke getName method!!
invoke setName method!!
invoke getName method!!
guojianjun
OK,成功。說了這麼多,那構造函數ModelMBeanAttributeInfo("name", "pepole name",getMethod, setMethod,nameDesc);裏的getMethod, setMethod方法有什麼用呢,我以爲好像沒什麼用,只是用來確認屬性類型,可讀可寫狀況。(我的觀點)
最後就是把這個MBean註冊到MBeanServer中管理,用Jconsole就能夠看到了:
ms.registerMBean(rmm, new ObjectName(
"guojje:type=notification,name=hello"));
(待續)