标准MBean所暴露的属性,操作,通知都是固定不变的,都固化在ClassNameMBean这个接口中,灵活度不足。
动态Mbean所暴露的特性是运行时确立,灵活度足够,但编码困难,因为你需要编码实现每一个属性,操作与通知。
模型Mbean也是一种动态Mbean,能够使你更快的编写动态MBean.
模型MBean的封装类RequiredModelMBean实现了ModelMBean接口,而ModelMBean接口继承自DynamicMBean,所以说模型Mbean也是一种动态Mbean。
首先定义需要管理的资源:
- 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~!!!");
- }
- }
测试类:
- 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"));
- }
运行结果:
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"));
(待续)