|
tomcat在启动过程中有个监听器GlobalResourcesLifecycleListener。
在初始化的时候,GlobalResourcesLifecycleListener这个类有个熟悉
/**
* The configuration information registry for our managed beans.
*/
protected static Registry registry = MBeanUtils.createRegistry();
这个时候,MBean工具类会创建注册,同时对MBean的配置文件进行解析。
/**
* Create and configure (if necessary) and return the registry of
* managed object descriptions.
*/
public synchronized static Registry createRegistry() {
if (registry == null) {
registry = Registry.getRegistry(null, null);
ClassLoader cl=ServerLifecycleListener.class.getClassLoader();
registry.loadDescriptors("org.apache.catalina.mbeans", cl);
registry.loadDescriptors("org.apache.catalina.authenticator", cl);
registry.loadDescriptors("org.apache.catalina.core", cl);
registry.loadDescriptors("org.apache.catalina", cl);
registry.loadDescriptors("org.apache.catalina.deploy", cl);
registry.loadDescriptors("org.apache.catalina.loader", cl);
registry.loadDescriptors("org.apache.catalina.realm", cl);
registry.loadDescriptors("org.apache.catalina.session", cl);
registry.loadDescriptors("org.apache.catalina.startup", cl);
registry.loadDescriptors("org.apache.catalina.users", cl);
registry.loadDescriptors("org.apache.catalina.ha", cl);
registry.loadDescriptors("org.apache.catalina.connector", cl);
registry.loadDescriptors("org.apache.catalina.valves", cl);
}
return (registry);
}
调用方法:registry.loadDescriptors("org.apache.catalina.mbeans", cl);
/** Lookup the component descriptor in the package and
* in the parent packages.
*
* @param packageName
*/
public void loadDescriptors( String packageName, ClassLoader classLoader ) {
String res=packageName.replace( '.', '/');
if( log.isTraceEnabled() ) {
log.trace("Finding descriptor " + res );
}
if( searchedPaths.get( packageName ) != null ) {
return;
}
String descriptors=res + "/mbeans-descriptors.ser";
URL dURL=classLoader.getResource( descriptors );
if( dURL == null ) {
descriptors=res + "/mbeans-descriptors.xml";
dURL=classLoader.getResource( descriptors );
}
if( dURL == null ) {
return;
}
log.debug( "Found " + dURL);
searchedPaths.put( packageName, dURL );
try {
if( descriptors.endsWith(".xml" ))
loadDescriptors("MbeansDescriptorsDigesterSource", dURL, null);
else
loadDescriptors("MbeansDescriptorsSerSource", dURL, null);
return;
} catch(Exception ex ) {
log.error("Error loading " + dURL);
}
return;
}
调用方法: loadDescriptors("MbeansDescriptorsDigesterSource", dURL, null);
/** Experimental. Will become private, some code may still use it
*
* @param sourceType
* @param source
* @param param
* @throws Exception
* @deprecated
*/
public void loadDescriptors( String sourceType, Object source, String param)
throws Exception
{
List mbeans=load( sourceType, source, param );
if( mbeans == null) return;
Iterator itr=mbeans.iterator();
while( itr.hasNext() ) {
Object mb=itr.next();
if( mb instanceof ManagedBean) {
addManagedBean((ManagedBean)mb);
}
}
}
上面的代码将XML配置文件解析为ManagedBean保存到类registry里面。
接下来看看tomcat是如何注册jmx:
看类StandardServer中的代码 818行:
if( oname==null ) {
try {
oname=new ObjectName( "Catalina:type=Server");
Registry.getRegistry(null, null)
.registerComponent(this, oname, null );
} catch (Exception e) {
log.error("Error registering ",e);
}
}
关键的这句 Registry.getRegistry(null, null).registerComponent(this, oname, null );
/** Register a component
* XXX make it private
*
* @param bean
* @param oname
* @param type
* @throws Exception
*/
public void registerComponent(Object bean, ObjectName oname, String type)
throws Exception
{
if( log.isDebugEnabled() ) {
log.debug( "Managed= "+ oname);
}
if( bean ==null ) {
log.error("Null component " + oname );
return;
}
try {
if( type==null ) {
type=bean.getClass().getName();
}
ManagedBean managed = findManagedBean(bean.getClass(), type);
// The real mbean is created and registered
DynamicMBean mbean = managed.createMBean(bean);
if( getMBeanServer().isRegistered( oname )) {
if( log.isDebugEnabled()) {
log.debug("Unregistering existing component " + oname );
}
getMBeanServer().unregisterMBean( oname );
}
getMBeanServer().registerMBean( mbean, oname);
} catch( Exception ex) {
log.error("Error registering " + oname, ex );
throw ex;
}
}
再看看方法
DynamicMBean mbean = managed.createMBean(bean);
/**
* Create and return a <code>ModelMBean</code> that has been
* preconfigured with the <code>ModelMBeanInfo</code> information
* for this managed bean, and is associated with the specified
* managed object instance. The returned <code>ModelMBean</code>
* will <strong>NOT</strong> have been registered with our
* <code>MBeanServer</code>.
*
* @param instance Instanced of the managed object, or <code>null</code>
* for no associated instance
*
* @exception InstanceNotFoundException if the managed resource
* object cannot be found
* @exception InvalidTargetObjectTypeException if our MBean cannot
* handle object references (should never happen)
* @exception MBeanException if a problem occurs instantiating the
* <code>ModelMBean</code> instance
* @exception RuntimeOperationsException if a JMX runtime error occurs
*/
public DynamicMBean createMBean(Object instance)
throws InstanceNotFoundException,
MBeanException, RuntimeOperationsException {
BaseModelMBean mbean = null;
// Load the ModelMBean implementation class
if(getClassName().equals(BASE_MBEAN)) {
// Skip introspection
mbean = new BaseModelMBean();
} else {
Class clazz = null;
Exception ex = null;
try {
clazz = Class.forName(getClassName());
} catch (Exception e) {
}
if( clazz==null ) {
try {
ClassLoader cl= Thread.currentThread().getContextClassLoader();
if ( cl != null)
clazz= cl.loadClass(getClassName());
} catch (Exception e) {
ex=e;
}
}
if( clazz==null) {
throw new MBeanException
(ex, "Cannot load ModelMBean class " + getClassName());
}
try {
// Stupid - this will set the default minfo first....
mbean = (BaseModelMBean) clazz.newInstance();
} catch (RuntimeOperationsException e) {
throw e;
} catch (Exception e) {
throw new MBeanException
(e, "Cannot instantiate ModelMBean of class " +
getClassName());
}
}
mbean.setManagedBean(this);
// Set the managed resource (if any)
try {
if (instance != null)
mbean.setManagedResource(instance, "ObjectReference");
} catch (InstanceNotFoundException e) {
throw e;
}
return (mbean);
}
代码贴完了。
解释下:
tomcat的jmx中的MBean使用的是DynamicMBean。
Registry.getRegistry(null, null).registerComponent(this, oname, null );
传入的是 StandardServer 对象,ObjectName对象。
根据bean的类或类型,获取当前MBean的配置。
ManagedBean managed = findManagedBean(bean.getClass(), type);
实例化
mbean = new BaseModelMBean();
设定
mbean.setManagedBean(this);
这里的this是指ManagedBean配置(上面步骤1中的ManagedBean对象managed)。
同时设定
mbean.setManagedResource(instance, "ObjectReference");
注册MBean
getMBeanServer().registerMBean( mbean, oname);
以上是MBean的注册全过程。 |
|