MBean:是Managed Bean的簡稱。在JMX中MBean表明一個被管理的資源實例,經過MBean中暴露的方法和屬性,外界能夠獲取被管理的資源的狀態和操縱MBean的行爲。事實上,MBean就是一個Java Object,同JavaBean模型同樣,外界使用自醒和反射來獲取Object的值和調用Object的方法,只是MBean更爲複雜和高級一些。
MBeanServer:MBean生存在一個MBeanServer中。MBeanServer管理這些MBean,而且代理外界對它們的訪問。而且MBeanServer提供了一種註冊機制,是的外界能夠經過名字來獲得相應的MBean實例。
JMX Agent:Agent只是一個Java進程,它包括這個MBeanServer和一系列附加的MbeanService。固然這些Service也是經過MBean的形式來發布。
Protocol Adapters and Connectors
JMX Agent經過各類各樣的Adapter和Connector來與外界(JVM以外)進行通訊。一樣外界(JVM以外)也必須經過某個Adapter和Connector來向JMX Agent發送管理或控制請求。
Adapter和Connector的區別在於:Adapter是使用某種Internet協議來與JMX Agent得到聯繫,Agent端會有一個對象(Adapter)來處理有關協議的細節。好比SNMP Adapter和HTTP Adapter。而Connector則是使用相似RPC的方式來訪問Agent,在Agent端和客戶端都必須有這樣一個對象來處理相應的請求與應答。好比RMI Connector。
JMX Agent能夠帶有任意多個Adapter,所以可使用多種不一樣的方式訪問Agent。
jmx中的三層結構:
Instrumentation 層:Instrumentation層主要包括了一系列的接口定義和描述如何開發MBean的規範。一般JMX所管理的資源有一個或多個MBean組成,所以這個資源能夠是任何由Java語言開發的組件,或是一個JavaWrapper包裝的其餘語言開發的資源。
Agent 層:Agent用來管理相應的資源,而且爲遠端用戶提供訪問的接口。Agent層構建在Intrumentation層之上,而且使用並管理Instrumentation層內部描述的組件。一般Agent由一個MBeanServer和多個系統服務組成。另外Agent還提供一個或多個Adapter或Connector以供外界的訪問。
JMX Agent並不關心它所管理的資源是什麼。
Distributed 層:Distributed層關心Agent如何被遠端用戶訪問的細節。它定義了一系列用來訪問Agent的接口和組件,包括Adapter和Connector的描述。
一個MBean是一個被管理的Java對象,有點相似於JavaBean,一個設備、一個應用或者任何資源均可以被表示爲MBean,MBean會暴露一個接口對外,這個接口能夠讀取或者寫入一些對象中的屬性,一般一個MBean須要定義一個接口,以MBean結尾, 例如: EchoMBean, 格式爲XXXMBean,這個是規範,必須得遵照。java
例如:app
package com.dxz.mbean.demo1; public interface EchoMBean { public void print(String yourName); } package com.dxz.mbean.demo1; public class Echo implements EchoMBean { public void print(String yourName) { System.out.println("Hi " + yourName + "!"); } }
Echo實現了EchoMBean接口,很簡單咱們只是print了hi yourName!
按照JMX的定義,是被管理的對象,如今咱們只是定義了該對象,並無被管理,接着咱們讓這個Echo類的實例對象被管理起來:函數
package com.dxz.mbean.demo1; import java.lang.management.ManagementFactory; import javax.management.MBeanServer; import javax.management.ObjectName; public class App { public static void main(String[] args) throws Exception { // 建立MBeanServer MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); // 新建MBean ObjectName, 在MBeanServer裏標識註冊的MBean ObjectName name = new ObjectName("com.dxz.demo1.mbean:type=Echo"); // 建立MBean Echo mbean = new Echo(); // 在MBeanServer裏註冊MBean, 標識爲ObjectName(com.dxz.mbean:type=Echo) mbs.registerMBean(mbean, name); // 在MBeanServer裏調用已註冊的EchoMBean的print方法 mbs.invoke(name, "print", new Object[] { "china sf"}, new String[] {"java.lang.String"}); Thread.sleep(Long.MAX_VALUE); } }
1. 首先咱們在App類中向ManagementFactory申請了一個MBeanServer對象
2. 接着咱們即然要使Echo的實例對象被管理起來,咱們就須要給這個對象一個標識,這個標識是ObjectName.注意這個ObjectName構造函數,這裏使用了(包名:type=類名)的形式.
3. 而後咱們經過mbs.registerMBean方法註冊了echo,並傳入了ObjectName在MBeanServer中標識該MBean.
4. 隨後咱們經過mbs.invoke方法調用了已經註冊的Echo的print方法,經過ObjectName找到該MBean, 並經過最後兩個參數,傳入print方法執行的參數,與參數的類型。
5. 最後咱們sleep主線程,等待其餘線程的調用.
經過這個例子咱們能夠看出,MBean的好處,在Echo的實例對象未被管理以前,咱們只能經過Echo對象的句柄,來調用Echo裏的public方法,在被管理以後,咱們能夠經過MBeanServer的句柄mbs來調用Echo對象的print方法。
更詳細的內容,咱們能夠經過JDK自帶工具jconsole或者 VisualVM 來查看MBean:工具
1.jconsolespa
jconsole的位置在%JAVA_HOME%/bin/jconsole.exe線程
開後會看到:代理
C:\Users\01107252>jconsolecode
選擇demo1.App而後點擊鏈接, 選擇MBean後會看到orm
這裏能夠直接調用Echo的print方法, 固然你們看到這裏邊還有好多其餘的table,包括概述、內存、線程、類、VM摘要、MBean。對象
2.VisualVM
VisualVM的位置在%JAVA_HOME%/bin/jvisualvm.exe
打開後通過鏈接咱們會看到相似的效果: