技术开发 频道

Pico\JMX\微容器以及对象的易管理性

【IT168 技术文档】

  一个新概念正在暗流涌动:PicoContainer/NanoContainer(以下简称pico)这样微容器正日益受到关注和广泛应用;J2SE5.0将JMX作为JDK基本API,这些技术都表明对象的易管理性(application/object manageability)呼之欲出。

  本文试图比较Pico、JMX这两种基于组件的容器管理技术,探讨对象易管理性方面的一些实践问题和模式。

  对象易管理性中首先是被管理的对象,也称为容器的基本模型单元,在JMX中它是Mbean;而在pico中则是普通Java对象,后者比前者更加广泛,也说明两者可结合使用。


  JMX和Pico

  我们进一步看看JMX的MBean特性和pico:

  1. 在JMX中,业务对象只要继承MBean接口就能够被纳入被管理范围。这些接口包括Standard MBean, DynamicMBean 或者 ModelMBean ,不同的MBean有不同的规则。而业务对象只要是Object,就可纳入Pico的容器管理范围,因此,pico可以做JMX最外层的套子。

  2.在JMX中,MBean只能通过MBean server访问;同样,在pico中,外界只能通过容器访问其中的Object。

  3.MBeans能向MBean Server注册,以一个唯一的字符串名,而在pico中也是如此,并且,pico不要求直接实例注册,而是推荐以Class注册,并且能够自动寻找Class需要的构造参数,可见,pico在这里增强了组件注册功能。

  4.调用Mbean的方法也很特别,只需MBean名称和方法名称组合的字符串就可以,最后通过invoke调即可; 在pico中,从容器中调用对象也是以String型的key实现调用,pico是以字符串调用对象;jmx是以字符串调用对象的方法; 两者可结合使用,关于字符串调用,pico增强容器NanoContainer甚至可以通过任何语言编制的字符串脚本都可以(smell like LOP面向语言编程?或者称为面向容器编程?)。

  JMX和pico结合比较调用实例如下:

Reader script = new StringReader("" + "import org.nanocontainer.script.groovy.NanoContainerBuilder\n" + "import org.microcontainer.jmx.JmxDecorationDelegate\n" + "\n" + "builder = new NanoContainerBuilder(new JmxDecorationDelegate())\n" + "pico = builder.container() {\n" + " component(key:javax.management.MBeanServer, instance:javax.management.MBeanServerFactory.createMBeanServer())\n" + " component(key:org.nanocontainer.testmodel.Wilma, class:org.nanocontainer.testmodel.WilmaImpl) {\n" + " jmx(key:'domain:wilma=default', operations:['helloCalled'], description:'jmx description text')\n" + " }\n" + "}");
  script是一段Groovy脚本,这段脚本是向Pico注册一个MBeanServer,并且向MBeanServer中注册一个MBean:接口是org.nanocontainer.testmodel.Wilma;实现是org.nanocontainer.testmodel.WilmaImpl,代码如下:
public interface Wilma {   void hello(); } public class WilmaImpl implements Wilma {   private boolean helloCalled;   public boolean helloCalled() {     return helloCalled;   }   public void hello() {     helloCalled = true;   } }
  NanoContainer可以运行装载这个脚本:
PicoContainer pico = buildContainer( new GroovyContainerBuilder(script, getClass().getClassLoader()), null, "SOME_SCOPE"); //从pico中获得MBeanServer, pico是最外层容器,负责管理MbeanServer和MBeans的关系。 MBeanServer mBeanServer = (MBeanServer)pico.getComponentInstance(MBeanServer.class); //JMX以字符串可以获得对象Wilma的属性和动作 ObjectName objectName = new ObjectName("domain:wilma=default"); MBeanInfo mBeanInfo = mBeanServer.getMBeanInfo(objectName); //pico以字符串为key实现调用对象的 Wilma wilma = (Wilma)pico.getComponentInstance(Wilma.class); wilma.hello();//调用WilmaImpl的hello方法 //jmx以字符串实现对象方法的调用,监察上句执行结果 Boolean called = (Boolean)mBeanServer.invoke( objectName, "helloCalled", null, null); //called结果为true, 也就是WilmaImpl的属性helloCalled结果为true,因为hello方法被调用。 assertTrue(called.booleanValue());

  从以上看出,JMX和Pico互相结合,可以起到互相结合的强大威力。

  从上面代码中,我们可以发现,对于容器中的对象,可以有两种不同的切入角度或是关注角度,也是所谓分散关注:一个是by pico的调用,如wilma.hello();另外一种是JMX提供的另外一种角度,通过JMX提供 的这种角度,我们可以发现或跟踪对象内容的状态,如WilmaImpl的属性helloCalled结果被发现改变。

  这非常类似现代的一些手术,无需开刀(不打开人体这个容器),通过激光或探头手段监察手术效果。

  既然被监察、跟踪,那么就意味着可以被管理了,JMX提供的这种角度被认为是可以将对象纳入被管理范围。

  以上这段代码构架是Pico和JMX的一个综合体,可以说启动了一个新的Java编程架构,称为什么合适呢?微容器 microcontainer!

  微容器与编程模式

  面向微容器编程目前是一种激动人心新的编程模式,总结上面这段代码,我们发现有一些面向微容器编程的规律或者称为模式。

  首先需要定义一个容器解读的配置,它是字符串的:

  一. 启动配置模式(JMX中称为MBeanForAppConfig pattern)

  目的:定义容器启动时需要装载的JavaBeans/MBeans信息。

  动机:容器启动时需要一些初始化配置,这样,容器启动可以装载这些对象。

  例如上面的Groovy脚本就是一段启动配置模式,在笔者的JdonSD 2.5框架中,是通过XML实现启动配置的,如:

<model key="userId" class ="com.jdon.controller.test.model.UserTest">   <actionForm name="userActionForm"/>   <handler class="com.jdon.controller.test.web.UserHandler"/>   <service ref="mappingManagerEJB">     <getMethod name="getUser" />     <createMethod name="create" />     <updateMethod name="update" />     <deleteMethod name="delete" />   </service> </model> <model key="addressId" class ="com.jdon.controller.test.model.AddressTest">   <actionForm name="addressActionForm"/>   <service ref="mappingManagerEJB">     <getMethod name="getAddress" />     <createMethod name="createAddress" />     <updateMethod name="updateAddress" />     <deleteMethod name="deleteAddress" />   </service> </model>

  二. 记录跟踪模式(JMX中称为MBeanWritesToLog pattern)

  目的:容器中的一些数据和状态需要拷贝到外部,如文件或图形输出等,以便跟踪。

  动机:Log日志记录是非常准确和常用的程序跟踪调试手段,通过Log4j等之类工具实现输出,可以对容器中状态掌握了解非常清楚。如上面代码中可以记录获得WilmaImpl的属性helloCalled结果为true,如果将其输出即可实现记录跟踪。


  三. 生命周期模式

  目的:微容器有创建和消亡时刻,因此必须处理好容器中每个对象生命周期。

  动机:生命周期是微容器的本质特征,处理好对象的生命周期,可以从设计上根本预防memory leak内存溢出或性能缓慢的基础缺陷,JMX在生命周期控制上非常深入,降低了编程复杂度。在Jdon论坛和2004年中国软件技术大会上我都反复强调生命周期的重要性,如果编程者考虑这点,说明对象在他的脑子里活起来了,而不是僵死的,这点也是全局工厂模式所不能替代的。


  微容器和全局工厂模式

  对于客户端来说,微容器和工厂模式性质是一致的,客户端不在乎你是微容器和工厂模式,都是获得创建对象,但是对于服务端来说就不一样了,工厂模式可能有很多类,这些类都没有被约束或被管理的,因此移植起来很麻烦;而微容器有自己的疆界,可以实现服务端的对象约束和管理,移植方便:提起容器就走,:),如下图:

0
相关文章