四、
Tomcat
中最簡單的
MBean
下面我們打開
Tomcat
源代碼,看看
Tomcat
中最簡單的一個
MBean
。在
Tomcat
的啓動引導類
Bootstrap.java
的
172
到
187
行,我們可以看到如下代碼:
ClassLoader classLoader = ClassLoaderFactory.createClassLoader
(locations, types, parent);
// Retrieving MBean server
MBeanServer mBeanServer = null;
if (MBeanServerFactory.findMBeanServer(null).size() > 0) {
mBeanServer =
(MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0);
} else {
mBeanServer = MBeanServerFactory.createMBeanServer();
}
// Register the server classloader
ObjectName objectName =
new ObjectName("Catalina:type=ServerClassLoader,name=" + name);
mBeanServer.registerMBean(classLoader, objectName);
4.1
上面的代碼首先使用
ClassLoaderFactory
工廠類創建一個
ClassLoader
;
4.2
然後在
MBeanServerFactory
這個工廠類中查找
MBeanServer
,如果沒有發現,就使用這個工廠類創建一個
MBeanServer
;
4.3
第三步是給剛纔創建的
ClassLoader
這個
MBean
取個名字“
Name: Catalina:type=ServerClassLoader,name=common
”,然後註冊到
MBeanServer
。
您如果在
JConsole
中觀察這個
MBean
,會發現這個
MBean
沒有向管理應用程序暴露任何屬性和方法,並且
Classloader
似乎也符合
JMX
命名規範,它也不是一個
DynamicBean
,這是爲什麼呢?首先,這個
Classloader
其實一個
StandardClassloader
,而不是
JDK
中缺省的
Classloader
,您如果打開
ClassLoaderFactory
的
createClassLoader
方法,馬上就可以看到這一點;另外,看看
StanderClassloader
的類簽名,我們會發現該類實現了
StandardClassLoaderMBean
接口,這是符合
JMX
命名規範的;請打開
StandardClassLoaderMBean
接口的源代碼,您會發現這是一個空接口,這意味着實現這個接口的
MBean
不會向管理程序暴露任何屬性和方法。
最後,希望這篇入門級的簡單介紹,能有助於大家理解
JMX
及
JMX
在
Tomcat
中的應用。
附錄:針對本文中的熱水器小例子,我們給出了一個簡單問題,即如何修改我們既有的代碼,讓這些代碼所在的資源能使用
JMX
管理?如果您稍微翻閱一下
Tomcat
的源代碼,您會發現,
Tomcat
的作者們在
JMX
升級時對已有源代碼的改動有點粗暴,勇猛有餘,優美不足。
org.apache.catalina.core
包中的關鍵組件,大部分後加了
preRegister()
、
getObjectName()
等等方法,在
init()
方法中又添加了一堆
Registry.getRegistry.unregisterComponent
或
registerComponent
代碼,這些方法其實這些
core
組件沒有直接關係,也不是這些
core
組件應該具有的功能,並且這些後添加的代碼及其類似。當然,這種情況在我們實際項目中更爲多見,主要原因是時間不足,資源有限等等。
如果要比較優美的解決上面的問題,我個人認爲,首先,保持現有代碼,然後對現有代碼進行擴展而不是大刀闊斧的修改已有代碼。就拿我們熱水器的簡單例子來說,我們不要修改
CentralHeaterImpl.java
的現有代碼,而是使用
Wrapper
設計模式,設計一個新類,然後將這個
CentralHeaterImpl
類適配成我們需要的
MBean
接口,具體實現如下:
a)
CentralHeaterDecoratorMBean.java
源代碼
package
carl.test.jmx;
/**
*
@author
carlwu
*
*/
public
interface
CentralHeater
Decorator
MBean {
/**
*
return
the
heater
provider
*
@return
*/
public
String getHeaterProvider();
/**
*
Get
current
temperature
of
heater
*
@return
the
temperature
of
the
heater
*/
public
int
getCurrentTemperature();
/**
*
Set
the
new
temperature
*
@param
newTemperature
*/
public
void
setCurrentTemperature(
int
newTemperature);
}
CentralHeaterDecorator
.java
的源代碼:
package
carl.test.jmx;
public
class
CentralHeaterDecorator
implements
CentralHeaterDecoratorMBean {
private
CentralHeaterImpl
centralHeater
;
public
CentralHeaterDecorator(CentralHeaterImpl theCentralHeater){
centralHeater
=theCentralHeater;
}
public
int
getCurrentTemperature() {
//
TODO
Auto-generated method stub
return
centralHeater
.getCurrentTemperature();
}
public
void
setCurrentTemperature(
int
newTemperature) {
//
TODO
Auto-generated method stub
centralHeater
.setCurrentTemperature(newTemperature);
}
public
String getHeaterProvider() {
//
TODO
Auto-generated method stub
return
centralHeater
.
HEATER_PROVIDER
;
}
public
String printCurrentTemperature() {
//
TODO
Auto-generated method stub
String returnMsg =
"Current temperature is:"
+
centralHeater
.getCurrentTemperature();
System.
out
.println(returnMsg);
return
returnMsg;
}
}
最後,請把
Agent
代碼中的下面一行:
CentralHeaterInf centralHeater =
new
CentralHeaterImpl();
改爲:
CentralHeaterDecoratorMBean centralHeater = new CentralHeaterDecorator(new CentralHeaterImpl());
其運行效果完全一樣,但我們完全沒有改動既有代碼。
JMX在Tomcat中的應用(四)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.