|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
其实产生见解的过程就是训练自己发现问题,分析问题的能力。根据以上的认识我想谈下传统的学习与通过视频独立学习的优缺点: 扩大SpringJMX导出器
为了利用扩大的ModelMBean,必要掩盖SpringMBeanExporter中的createModelMBean()办法。由于能够注进拆卸器属性,以是必需晓得它大概不是我所等候的这一现实。能够在机关函数中设置所必要的拆卸器,可是当拆卸器改动时必要前往一个一般ModelMBean。所要做的就是缓存一个MBeanInfoAssembler的当地援用,并在创立新的ModelMBean时反省它是甚么范例的。清单2显现了一切这些改动:
清单2.MBeanDescriptorEnabledExporter- packagecom.claudeduguay.mbeans.spring;importjavax.management.*;importjavax.management.modelmbean.*;importorg.springframework.jmx.export.*;importorg.springframework.jmx.export.assembler.*;publicclassMBeanDescriptorEnabledExporterextendsMBeanExporter{protectedMBeanInfoAssemblermBeanInfoAssembler;publicMBeanDescriptorEnabledExporter(){setAssembler(newMBeanDescriptorBasedAssembler());}publicModelMBeancreateModelMBean()throwsMBeanException{if(mBeanInfoAssemblerinstanceofMBeanDescriptorBasedAssembler){returnnewModelMBeanExtension();}returnsuper.createModelMBean();}publicvoidsetAssembler(MBeanInfoAssemblermBeanInfoAssembler){this.mBeanInfoAssembler=mBeanInfoAssembler;super.setAssembler(mBeanInfoAssembler);}}
复制代码 在利用这个扩大的类时,能够用尺度Spring言语改动拆卸器,并在必要时回到默许的举动。在年夜多半情形下,假如终极绕过扩大,那末就不值得利用这个版本。不外,假如想要以新的定制拆卸器利用扩大的ModelMBean,那末如今能够如许做。
构建一个定制的拆卸器
这个定制拆卸器的次要义务是查找与办理的类有关的元数据映照文件。找到这个文件后,就装载它并天生需要的ModelMBeanInfo实例。为此,我只是完成了SpringMBeanInfoAssembler实例创建这个文件的相干类路径,用静态MBeanDescriptorUtil.read()办法装载它并前往了局,如清单3所示:
清单3.MBeanDescriptorBasedAssembler- packagecom.claudeduguay.mbeans.spring;importjava.io.*;importjavax.management.modelmbean.*;importorg.springframework.core.io.*;importorg.springframework.jmx.export.assembler.*;importcom.claudeduguay.mbeans.model.*;publicclassMBeanDescriptorBasedAssemblerimplementsMBeanInfoAssembler{publicModelMBeanInfogetMBeanInfo(ObjectmanagedBean,StringbeanKey){Stringname=managedBean.getClass().getName();Stringpath=name.replace(.,/)+".mbean.xml";ClassPathResourceresource=newClassPathResource(path);InputStreaminput=null;try{input=resource.getInputStream();MBeanDescriptordescriptor=MBeanDescriptorUtil.read(input);returndescriptor.createMBeanInfo();}catch(Exceptione){thrownewIllegalStateException("Unabletoloadresource:"+path);}finally{if(input!=null){try{input.close();}catch(Exceptionx){}}}}}
复制代码 这个MBeanDescriptorBasedAssembler疏忽bean键参数并间接用受管bean援用创立所需的ModelMBeanInfo实例。
示例
在本文其他部分,我将侧重展现这个SpringJMX扩大的利用。为此,利用一个设想的服务,它开放两个办法和一个属性,因而体现了典范的用例。
ExampleService是一个Java对象,它在被挪用时只是向把持台举行输入,如清单4所示:
清单4.ExampleService- packagecom.claudeduguay.jmx.demo.server;publicclassExampleService{protectedStringpropertyValue="defaultvalue";publicExampleService(){}publicStringgetPropertyValue(){System.out.println("ExampleService:GetPropertyValue");returnpropertyValue;}publicvoidsetPropertyValue(StringpropertyValue){System.out.println("ExampleService:SetPropertyValue");this.propertyValue=propertyValue;}publicvoidstartService(){System.out.println("ExampleService:StartServiceCalled");}publicvoidstopService(){System.out.println("ExampleService:StopServiceCalled");}}
复制代码 对办理员友爱的动静
这个扩大的形貌符能够几近间接联系关系属性和操纵。形貌符办法优于内省式办法的次要一点是能够供应更特定的动静。关照形貌符的设置选项有赖于范例(XML)属性的定名标准。实践的名字是恣意的,可是代码会被范例中的set.name、before.name和after.name款式触发。在这类情形下,我将set关照与propertyValue(JMX)属性联系关系,将before与after关照与startService()与stopService()办法联系关系。一样,这些扩大使我能够很好使用形貌性的动静。
在清单5中,能够看到界说了一个属性和两个办法。关照形貌符界说了办法的之前和以后事务和一个属性设置关照:
清单5.ExampleService.mbean.xml- <?xmlversion="1.0"?><mbeanname="ExampleService"description="ExampleService"type="com.claudeduguay.jmx.demo.server.ExampleService"><attributename="propertyValue"description="PropertyValueAccess"type="java.lang.String"readable="true"writable="true"/><operationname="stopService"description="StopExampleService"/><operationname="startService"description="StartExampleService"/><notificationname="PropertyValueSet"types="example.service.set.propertyValue"description="PropertyValuewasset"/><notificationname="BeforeStartService"types="example.service.before.startService"description="ExampleServiceisStarting"/><notificationname="AfterStartService"types="example.service.after.startService"description="ExampleServiceisStarted"/><notificationname="BeforeStopService"types="example.service.before.stopService"description="ExampleServiceisStopping"/><notificationname="AfterStopService"types="example.service.after.stopService"description="ExampleServiceisStopped"/></mbean>
复制代码 设置服务器
要在客户机/服务器情况中运转这个例子,必要设置和启动一个MBeanServer实例。为此,我利用Java5.0MBeanServer实例,它包管我可使用JVM中供应的办理扩大,同时办理本人的代码。假如乐意,还能够运转MBeanServer的多个实例,您乐意的话也能够本人试一试作为实习。
就像Java5.0一样,Spring框架使您能够设置本人的MBeanServer实例。我选择利用Java5.0,由于它撑持JSR-160毗连器,我的客户机代码会必要它。
清单6.SpringJmxServer- packagecom.claudeduguay.jmx.demo.server;importorg.springframework.context.*;importorg.springframework.context.support.*;importmx4j.tools.adaptor.http.*;/**TousetheSpringJmxServer,usethefollowingcommandline*argumentstoactivatetheJava1.5JMXServer.**-Dcom.sun.management.jmxremote.port=8999*-Dcom.sun.management.jmxremote.ssl=false*-Dcom.sun.management.jmxremote.authenticate=false*/publicclassSpringJmxServer{publicstaticvoidmain(String[]args)throwsException{StringSPRING_FILE="com/claudeduguay/jmx/demo/server/SpringJmxServer.xml";ApplicationContextcontext=newClassPathXmlApplicationContext(SPRING_FILE);HttpAdaptorhttpAdaptor=(HttpAdaptor)context.getBean("HttpAdaptor");httpAdaptor.start();}}
复制代码 因为有了MBeanDescriptorEnabledExporter,服务器的Spring设置文件十分复杂。除声明ExampleService,我增添了开放一个HTTP适配器和毗连XSLTProcessor到HttpAdaptor所必要的MX4J项。注重这是Spring的IOC完成十分有效的一个范畴。清单7显现了我的SpringJmxServer实例的Spring设置文件:
清单7.SpringJmxServer.xml- <?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd"><beans><beanid="exporter"class="com.claudeduguay.mbeans.spring.MBeanDescriptorEnabledExporter"><propertyname="beans"><map><entrykey="Services:name=ExampleService"value-ref="ExampleService"/><entrykey="MX4J:name=HttpAdaptor"value-ref="HttpAdaptor"/><entrykey="MX4J:name=XSLTProcessor"value-ref="XSLTProcessor"/></map></property></bean><beanid="XSLTProcessor"class="mx4j.tools.adaptor.http.XSLTProcessor"/><beanid="HttpAdaptor"class="mx4j.tools.adaptor.http.HttpAdaptor"><propertyname="processor"ref="XSLTProcessor"/><propertyname="port"value="8080"/></bean><beanid="ExampleService"class="com.claudeduguay.jmx.demo.server.ExampleService"/></beans>
复制代码 假如乐意(假定您遵守了我的设置),那末如今就能够运转这个服务器了。它会注册ExampleService并运转HTTP适配器。不要健忘利用正文中提到的命令行参数启动Java5.0MBeanServer,不然会失掉默许实例,客户机示例就不克不及事情了。
运转客户机代码
启动服务器后,能够运转如清单8所示的客户机代码看看会产生甚么。这段代码完成了JMXNotificationListener接口,如许就能够交互式地看到所产生的事变。毗连后,能够注册监听器,然后触发几个挪用、启动和中断服务、设置和获得属性。在每种情形下,都应该在把持台上看到一个确认操纵的关照动静。
清单8.SpringJmxClient- packagecom.claudeduguay.jmx.demo.client;importjava.util.*;importjavax.management.*;importjavax.management.remote.*;publicclassSpringJmxClientimplementsNotificationListener{publicvoidhandleNotification(Notificationnotification,Objecthandback){System.out.println("Notification:"+notification.getMessage());}publicstaticvoidmain(String[]args)throwsException{SpringJmxClientlistener=newSpringJmxClient();Stringaddress="service:jmx:rmi:///jndi/rmi://localhost:8999/jmxrmi";JMXServiceURLserviceURL=newJMXServiceURL(address);Map<String,Object>environment=null;JMXConnectorconnector=JMXConnectorFactory.connect(serviceURL,environment);MBeanServerConnectionmBeanConnection=connector.getMBeanServerConnection();ObjectNameexampleServiceName=ObjectName.getInstance("Services:name=ExampleService");mBeanConnection.addNotificationListener(exampleServiceName,listener,null,null);mBeanConnection.invoke(exampleServiceName,"startService",null,null);mBeanConnection.setAttribute(exampleServiceName,newAttribute("propertyValue","newvalue"));System.out.println(mBeanConnection.getAttribute(exampleServiceName,"propertyValue"));mBeanConnection.invoke(exampleServiceName,"stopService",null,null);}}
复制代码 因为HTTP适配器也是可用的,能够试着利用MX4J(经由过程一个到端口8080的扫瞄器毗连)办理一样的办法和属性。假如同时让客户机代码运转,那末也会看到这些操纵的关照。
停止语
在本文中,我展现了怎样扩大Spring的JMX撑持以满意使用程序的特定需求。在这里,我利用了Spring的基于容器的系统布局和AOP框架来为JMX办法和属性增添关照事务。固然,我只触及到了SpringJMX才能的外相。还能够有很多其他扩大,Spring和JMX都是很年夜的主题,每个都值得进一步研讨。
首先java功能强大的背后是其复杂性,就拿web来说,当今流行的框架有很多,什么struts,spring,jQuery等等,而这无疑增加了java的复杂性。 |
|