上一节分析了 Registry 类的功能,其引用 management 包中所有的类,也就是 JDK 支持 JMX 功能的类,本节将继续分析类图的其他部分。
JMX 的类图截取如下:
分析类图得到几点信息如下: 第一,JmxBeanServer 和 DefaultMBeanServerInterceptor 类,它们都是 MBeanServer 接口的实现类,即它们都是 MBeanServer 类型。Tomcat 中引用是通过调用 JmxBeanServer 的静态工厂方法 newMBeanServer() 来获取 MBeanServer 实例的。
第二,JmxBeanServer 类的成员变量 mbsInterceptor 就是在其构造函数中直接 new 的一个 DefaultMBeanServerInterceptor 对象,然后 JmxBeanServer 实现 MBeanServer 接口的所有的方法都是委派 mbsInterceptor 实现的。
第三,再看看 DefaultMBeanServerInterceptor 类,它所实现的 MBeanServerInterceptor 接口的方法定义,与底部右下角的 MBeanInstantiator 类提供的方法是一致的;而 DefaultMBeanServerInterceptor 类关联了一个 MBeanInstantiator 成员变量。由此可知,这也是简单的委派来实现接口的方法。
第四,Repository 类,是一个容器类,用来管理 MBean 的增删改查的。MBeanInstantiator 类是一个普通的 class,没有实现任何接口,它是通过反射来创建 Java 对象的,就是一个反射的工具类。
通过源码跟踪,可以可以绘制出整个调用过程的时序图如下:
JMX 的 HelloWorld 实现也很简单,Agent 端的代码就是获取一个 MBeanServer 实例的过程,JDK 提供的 API 调用 ManagementFactory 的 getPlatformMBeanServer()。
- public static void main(String[] args) throws JMException,
- Exception {
- MBeanServer server = ManagementFactory.getPlatformMBeanServer();
- ObjectName helloName = new ObjectName("jmxBean:name=hello");
- // create mbean and register mbean
- server.registerMBean(new Hello(), helloName);
- Thread.sleep(60 * 60 * 1000);
- }
这里,我只关注那一行 JMX 的 API 方法,而详细的 JMX 的 HelloWorld 程序,请参考:http://damies.iteye.com/blog/51788
首先,配置 tomcat 的 jmx 参数后,我们可以通过 jconsole.exe 来监控 tomcat 服务器的运行状况,除了 MBean 外,还可以监控各个线程当前的状态、堆内存情况。
其次,分析源码后,我们也能学到一点 JDK 的编码思想,就是凡是一个接口的实现方法中有 get、set 时,它的实现类必定包含一个该类型的成员变量。还有一点,就是接口有父接口的情况下,其实现类可以只提供一个接口的方法,而另外接口的方法可以通过委派自身的成员变量来完成。
我以为这样的好处是可以控制当前实现类的代码量不至于过多,毕竟就是一行调用的代码,比完全实现 N 个方法的代码量,相比之下少了太多了。
最后,Tomcat 真是博大精深,一行简单的 Registry.registerComponent() 就能牵出这么多的类,而我也只是大概分析了流程,浅尝辄止。这种学习方式,到底又能学到多少精华的东西呢?天知道,罢了,想多了,就是太难为自己了。唯有保持继续跟踪的心态,借以安慰自己匮乏的心灵吧。
来源: http://blog.csdn.net/wojiushiwo945you/article/details/73699327