java有一个动态管理应用程序的动能叫jmx(Java Management Extensions,即Java管理扩展)。它向外部提供了接口(主要是2种:jmxrmi和http),用于获取程序内部信息或动态控制程序
jmx可以理解为jvm开了一个端口,通过该端口可以直接访问jvm堆中的对象(前提是该对象必须先注册到jmx,否则jmx允许你访问任何对象,太不安全了)
代码依赖2个jar包
ControllerMBean.java
public interface ControllerMBean { public void setName(String name); public String getName(); public void setName1(String name1); public String getName1(); public String status(); public void start(); public void stop(); }
Controller.java
public class Controller implements ControllerMBean { private String name; private String name1; public void setName(String name) { this.name = name; System.out.println("set name:"+name); } public String getName() { System.out.println("get name:"+name); return this.name; } public void setName1(String name1) { this.name1 = name; System.out.println("set name1:"+name1); } public String getName1() { System.out.println("get name1:"+name1); return this.name1; } public String status() { System.out.println("status"); return "this is a Controller MBean,name is " + this.name; } public void start() { System.out.println("start"); // TODO Auto-generated method stub } public void stop() { System.out.println("stop"); // TODO Auto-generated method stub } }
Main.java
import javax.management.*; import javax.swing.*; import java.lang.management.ManagementFactory; public class Main { /** * @param args * @throws NullPointerException * @throws MalformedObjectNameException * @throws NotCompliantMBeanException * @throws MBeanRegistrationException * @throws InstanceAlreadyExistsException */ public static void main(String[] args) throws MalformedObjectNameException,Exception { //获得MBeanServer实例 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();//可在jconsole中使用 //创建MBean ControllerMBean controller = new Controller(); System.out.println(controller.hashCode()); //将MBean注册到MBeanServer中 mbs.registerMBean(controller, new ObjectName("MyappMBean:type=MyMetric")); //创建适配器,用于能够通过浏览器(http)访问MBean,如果没有以下四句代码,则只能通过jconsole管理 // HtmlAdaptorServer adapter = new HtmlAdaptorServer(); // adapter.setPort(9797); // mbs.registerMBean(adapter, new ObjectName( // "MyappMBean:name=html")); // adapter.start(); Thread.sleep(Long.MAX_VALUE); } }
import java.util.Arrays; import java.util.Set; import java.util.TreeSet; import javax.management.JMX; import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; public class Client { public static void main(String[] args) throws Exception { JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi"); JMXConnector jmxc = JMXConnectorFactory.connect(url, null); System.out.println("-------------- All Domain -----------------"); MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); // Get domains from MBeanServer String domains[] = mbsc.getDomains(); Arrays.sort(domains); for (String domain : domains) { System.out.println("\tDomain = " + domain); } System.out.println("-------------- MBean -----------------"); System.out.println("MBean count = " + mbsc.getMBeanCount()); Set<ObjectName> names = new TreeSet<ObjectName>(mbsc.queryNames(null, null)); for (ObjectName name : names) { System.out.println("\tObjectName = " + name); } System.out.println("-------------- set metric -----------------"); ObjectName mbeanName = new ObjectName("MyappMBean:type=MyMetric"); ControllerMBean mbeanProxy = JMX.newMBeanProxy(mbsc, mbeanName, ControllerMBean.class, true); mbeanProxy.setName("fang1"); System.out.println("set name: fang1"); System.out.println("-------------- get metric -----------------"); System.out.println("getname = " + mbeanProxy.getName()); } }