JMX的一个完整例子

import java.io.IOException;
import java.lang.reflect.Method;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.management.InstanceNotFoundException;
import javax.management.JMException;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MBeanServerInvocationHandler;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;

public class ManagementContext implements Service {
	
	private MBeanServer beanServer;
	
	private final AtomicBoolean started = new AtomicBoolean(false);
	
	private String connectorHost = "localhost";
	
	private int connectorPort = 1099;
	
	private final AtomicBoolean connectorStarting = new AtomicBoolean(false);
	
	
	public ManagementContext() {
		this(null);
	}

	public ManagementContext(MBeanServer server) {
		this.beanServer = server;
	}

	
	
	@Override
	public void start() throws Exception {
		if(started.compareAndSet(false, true)) {
			
			if(connectorHost == null) {
				connectorHost = "localhost";
			}
			
			getMBeanServer();
			
			if(connectorServer != null) {
				try {
					
					if(getMBeanServer().isRegistered(namingServiceObjectName)) {
						getMBeanServer().invoke(namingServiceObjectName, "start", null, null);
					}
				} catch(Throwable ignore) {
					// log exception info
				}
			}
			
			
			Thread thread = new Thread("JMX connector") {
				public void run() {
					try {
						JMXConnectorServer server = connectorServer;
						
						if(started.get() && server != null) {
							System.out.println("Starting JMXConnectorServer...");
							connectorStarting.set(true);
							try {
								server.start();
							} finally {
								connectorStarting.set(false);
							}
						}
					} catch(IOException e) {
						e.printStackTrace();
					} finally {
						//
					}
					
				}
				
			};
			
			thread.setDaemon(true);
			thread.start();
		}
		
	}
	
	protected MBeanServer getMBeanServer() {
		if(this.beanServer == null) {
			this.beanServer = findMBeanServer();
		}
		return beanServer;
	}
	
	private boolean useMBeanServer = true;
	
	private boolean createMBeanServer = true;
	
	private boolean findTigerMbeanServer = true;
	
	private boolean createConnector = true;
	
	protected synchronized MBeanServer findMBeanServer() {
		MBeanServer result = null;
		
		try {
			if(useMBeanServer)  {
				if(findTigerMbeanServer) {
					result = findTigerMBeanServer();
				}
				
				if(result == null) {
					List<MBeanServer> list = MBeanServerFactory.findMBeanServer(null);
					if(list != null && list.size() > 0) {
						result = list.get(0);
					}
				}
				
				if(result == null && createMBeanServer) {
					result = createMBeanServer();
				}
			}
		} catch(NoClassDefFoundError e) {
			// log exception
			e.printStackTrace();
		} catch (Throwable e) {
			// log info
			e.printStackTrace();
		}
		
		return result;
	}
	
	private static final String DEFAULT_DOMAIN = "org.fantasy";
	
	private String jmxDomainName = DEFAULT_DOMAIN;
	
	private boolean locallyCreateMBeanServer;
	
	protected MBeanServer createMBeanServer() throws MalformedObjectNameException, NullPointerException, IOException {
		MBeanServer mbeanServer = MBeanServerFactory.createMBeanServer(jmxDomainName);
		locallyCreateMBeanServer = true;
		if(createConnector) {
			createConnector(mbeanServer);
		}
		return mbeanServer;
	}

	public MBeanServer findTigerMBeanServer() {
		String name = "java.lang.management.ManagementFactory";
		Class<?> type = loadClass(name, ManagementContext.class.getClassLoader());
		if(type != null) {
			
			try {
				Method method = type.getDeclaredMethod("getPlatformMBeanServer", new Class[0]);
				if(method != null) {
					Object answer = method.invoke(null, new Object[0]);
					if(answer instanceof MBeanServer) {
						if(createConnector) {
							createConnector((MBeanServer)answer);
						}
						return (MBeanServer)answer;
					} else {
						// log info 
					}
					
				} else {
					// log info 
				}
			} catch (Exception e) {
				// log exception
			}
		} else {
			// log info 
		}
		
		return null;
	}
	
	private Registry registry;
	
	private ObjectName namingServiceObjectName;
	
	private int rmiServerPort;
	
	private String connectorPath = "/jmxrmi";
	
	private Map<String, ?> environment;
	
	private JMXConnectorServer connectorServer;
	
	private void createConnector(MBeanServer mbeanServer) throws IOException, MalformedObjectNameException, NullPointerException {
		if(registry == null) {
			registry = LocateRegistry.createRegistry(connectorPort);
		}
		namingServiceObjectName = ObjectName.getInstance("naming:type=rmiregistry");
		String rmiServer = "";
		if(rmiServerPort != 0) {
			rmiServer = "" + getConnectorHost() + ":" + rmiServerPort;
		}
		/**  service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi  */
		String serviceURL = "service:jmx:rmi://" + rmiServer + "/jndi/rmi://" +getConnectorHost()+":" + connectorPort + connectorPath;
		JMXServiceURL url = new JMXServiceURL(serviceURL);
		connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, environment, mbeanServer);
	}
	
	
	
	public int getConnectorPort() {
		return connectorPort;
	}

	public String getConnectorHost() {
		return connectorHost;
	}
	
	private final Map<ObjectName, ObjectName> registeredMBeanNames = new ConcurrentHashMap<ObjectName, ObjectName>();

	public void stop() throws Exception {
		if(started.compareAndSet(true, false)) {
			MBeanServer mbeanServer = getMBeanServer();
			
			if(mbeanServer != null) {
				for (Map.Entry<ObjectName, ObjectName> entry : registeredMBeanNames.entrySet()) {
                    ObjectName actualName = entry.getValue();
                    if (actualName != null && beanServer.isRegistered(actualName)) {
                        mbeanServer.unregisterMBean(actualName);
                    }
                }
			}
			
			registeredMBeanNames.clear();
			
			JMXConnectorServer server = connectorServer;
			connectorServer = null;
			if(server != null) {
				if(!connectorStarting.get()) {
					server.stop();
				}
			}

			if(namingServiceObjectName != null && getMBeanServer().isRegistered(namingServiceObjectName)) {
				getMBeanServer().invoke(namingServiceObjectName, "stop", null, null);
				getMBeanServer().unregisterMBean(namingServiceObjectName);
			}
			namingServiceObjectName = null;
			
			
			if(locallyCreateMBeanServer && beanServer != null) {
				List<MBeanServer> list = MBeanServerFactory.findMBeanServer(null);
				if(list != null && !list.isEmpty() && list.contains(beanServer)) {
					MBeanServerFactory.releaseMBeanServer(mbeanServer);
				}
			}
			beanServer = null;
		}
		
		if(registry != null) {
			UnicastRemoteObject.unexportObject(registry, true);
			registry = null;
		}
	}
	
	
	private static Class<?> loadClass(String name, ClassLoader loader) {
		try {
			return loader.loadClass(name);
		} catch (ClassNotFoundException e) {
			try {
				return Thread.currentThread().getContextClassLoader().loadClass(name);
			} catch (ClassNotFoundException e1) {
				return null;
			}
		}
	}
	
	
	public ObjectName createCustomComponentMBeanName(String type, String name) {
		ObjectName result = null;
		String tmp = jmxDomainName + ":" + "type=" + sanitizeString(type) + ",name=" + sanitizeString(name);
		try {
			result = new ObjectName(tmp);
		} catch (MalformedObjectNameException e) {
			e.printStackTrace();
			// exception
		}
		return result;
	}
	
	
	public Object getAttribute(ObjectName name, String attribute) throws Exception {
		return getMBeanServer().getAttribute(name, attribute);
	}
	
	
	public Object newProxyInstance(ObjectName objectName, Class<?> interfaceClass, boolean notificationBroadcaster) {
		return MBeanServerInvocationHandler.newProxyInstance(getMBeanServer(), objectName, interfaceClass, notificationBroadcaster);
	}
	
	
	public ObjectInstance registerMBean(Object bean, ObjectName name) throws Exception {
		ObjectInstance result = getMBeanServer().registerMBean(bean, name);
		this.registeredMBeanNames.put(name, result.getObjectName());
        return result;
	}
	
	public Set<ObjectName> queryNames(ObjectName name, QueryExp query) throws Exception {
		if (name != null) {
			ObjectName actualName = this.registeredMBeanNames.get(name);
			if(actualName != null) {
				return getMBeanServer().queryNames(actualName, query);
			}
		}
		return getMBeanServer().queryNames(name, query);
	}
	
	
	private static String sanitizeString(String in) {
		String result = null;
        if (in != null) {
            result = in.replace(':', '_');
            result = result.replace('/', '_');
            result = result.replace('\\', '_');
        }
        return result;
	}
	
	public ObjectInstance getObjectInstance(ObjectName name) throws InstanceNotFoundException {
		return getMBeanServer().getObjectInstance(name);
	}
	
	public void unregisterMBean(ObjectName name) throws JMException {
		
        ObjectName actualName = this.registeredMBeanNames.get(name);
        
        if (

        		beanServer != null && 
        		actualName != null && 
        		beanServer.isRegistered(actualName) && 
        		this.registeredMBeanNames.remove(name) != null

        ) {
        	
            beanServer.unregisterMBean(actualName);
            
        }
        
    }
	
	
	public static void main(String[] args) throws Exception {
		ManagementContext managementContext = new ManagementContext();
		managementContext.start();
		ObjectName objectName = managementContext.createCustomComponentMBeanName("20160113", "1507");
		Hello hello = new Hello();
		ObjectInstance objectInstance = managementContext.registerMBean(hello, objectName);
		objectInstance.getClassName();
		String name = (String)managementContext.getAttribute(objectName, "Name");
		System.out.println(name);


		Set<ObjectName> names = managementContext.queryNames(objectName, null);
		for(ObjectName oName : names) {
			System.out.println(oName);
		}
		
//		managementContext.stop();
		Thread.sleep(Long.MAX_VALUE);
	}
	
}



public interface Service {

	public void start() throws Exception;
	
	public void stop() throws Exception;

}
 

猜你喜欢

转载自zhangyu84849467.iteye.com/blog/2270351