原帖地址:http://blog.sina.com.cn/s/blog_54cd1aa30100s0n5.html
JBoss 启动过程
JBoss的基本框架是JMX,JBoss的服务基本上是通过注册到一个MBeanServer来实现的,因此具有很好的扩展性,好像Weblogic和AdventNet的基本结构也是基于jmx的。JBoss的服务类大都实现了ServiceMBean接口,在管理上也方便了许多。
a) %JBOSS_CLASSPATH%;
b) %JAVA_HOME%/lib/tools.jar;
c) run.jar
d) ../lib/crimson.jar;
e) -Djavax.xml.parsers.DocumentBuilderFactory=org.apache.crimson.jaxp.DocumentBuilderFactoryImpl
f) -Djavax.xml.parsers.SAXParserFactory=org.apache.crimson.jaxp.SAXParserFactoryImpl
java %JAXP% -classpath "%JBOSS_CLASSPATH%" org.jboss.Main
String cn = "default";
String patchDir = null;
…………
final String confName = cn;
final String patchDirName = patchDir;
配置文件放在“/conf/” + confName + “/”下面。对于jboss2.4 + Catalina, 在运行run.bat文件时指定了参数catalina,实际使用的是/conf/catalina目录下的配置文件。
URL jbossProps = Main.class.getClassLoader().getResource (confName+”/jboss.properties”);
InputStream propertiesIn = Main.class.getClassLoader().getResourceAsStream (confName+”/jboss.properties”);
if ( propertiesIn != null ) {
System.getProperties().load(propertiesIn);
}
if( System.getProperty(“jboss.home”) == null ) {
…………
System.setProperty(“jboss.home”, homeDir.getCanonicalPath());
}
// Set the JAAS login config file if not already set
if( System.getProperty(“java.security.auth.login.config”) == null )
{
…………
System.setProperty(“java.security.auth.login.config”, loginConfig.toExternalForm());
}
final MBeanServer server = MBeanServerFactory.createMBeanServer();
javax.management.MBeanServerFactory中的这个方法是这样实现的:
public static MBeanServer createMBeanServer () {
MBeanServer mbeanServer = new MBeanServerImpl() ;
addMBeanServer(mbeanServer) ; //存储MBeanServer
return mbeanServer ;
}
1. 这个方法根据缺省的域创建了一个符合MBeanServer接口的实例。
2. 在MBeanServerFactory中有一个静态私有变量 MBeanServerList 用于存储MBeanServer,这样以后查找BeanServer时候可以找到已创建的server。
com.sun.management.jmx.MBeanServerImpl时这样实现的:
public MBeanServerImpl() {
initialize(new RepositorySupport(), null);
}
private void initialize(RepositorySupport repository, String domain) {
}
MBeanServerImpl有一个私有变量repository用于存储MBean
initialize函数执行下列动作:
1. 如果domain为null或者是空字符串,将自己的域设置为repository的缺省域 (”DefaultDomain”)。否则将自己和repository的域设置为domain.
2. 设置查询服务的方式,目前的实现是由MBeanServer负责查询
3. 创建MetaData实例(在注册时候检查MBean的接口)
4. 创建标识MBeanServer的MBean: MBeanServerDelegateObject
5. 注册MBeanServerDelegateObject
6. 保存类加载器,包括加载MBeanServerImpl类的加载器和系统类加载器。
URL[] urls = {confDirectory};
获得所有补丁文件
…………
MLet mlet = new NullURLsMLet(urls);
NullURLsMLet扩展了Mlet类,并调用父类的构造函数进行初始化。
server.registerMBean(mlet, new ObjectName(server.getDefaultDomain(), “service”, “MLet”));
把mlet设置为本应用的类加载器
Thread.currentThread().setContextClassLoader(mlet);
URL mletConf = mlet.getResource("jboss.conf");
Set beans = (Set)mlet.getMBeansFromURL(mletConf);
…………
server.invoke(new ObjectName(":service=Configuration"), "loadConfiguration", new Object[0], new String[0]);
server.invoke(new ObjectName(":service=Configuration"), "saveConfiguration", new Object[0] , new String[0]);
server.invoke(new ObjectName(":service=ServiceControl"), "init", new Object[0] , new String[0]);
server.invoke(new ObjectName(":service=ServiceControl"), "start", new Object[0] , new String[0]);
ConfigurationService |
ServiceMBeanSupport |
NotificationBroadcasterSupport |
ServiceMBean |
MBeanRegistration |
ConfigurationServiceMBean |
Service |
用DOM读取配置文件
doc = parser.parse(new InputSource(new StringReader(sbufData.toString())));
//创建相应的MBean
create(doc);
//设置MBean的属性并注册相应的服务
load(doc);
//把配置文件中所指明的MBean加载到server中
NodeList nl = configuration.getElementsByTagName_r("mbean");
for (int i = 0; i < nl.getLength(); i++)
{
…………
MBeanInfo info;
try {
info = server.getMBeanInfo(objectName);
} catch (InstanceNotFoundException e) {
…………
//创建MBean
server.createMBean(code,objectName,loader, constructor.params, constructor.signature);
info = server.getMBeanInfo(instance.getObjectName());
…………
}
}
设置相应MBean的属性
Object value = attributeText;
server.setAttribute(objectName, new Attribute(attributeName, value));
注册服务
registerService(objectName, info, mbeanElement);
server.invoke(serviceControl, "register", args, signature);
将MBeanServer中注册的MBean的信息写入jboss-auto.jcml文件中
Service |
ServiceControlMBean |
ServiceControl |
MBeanRegistration |
ServiceControl被用来管理JBoss服务的生命周期
在配置服务的时候,ConfigurationService.load方法调用serviceControl.register方法注册了很多MBean,这些MBean都是Service的子类,即他们都有自己的init, start, stop, destroy方法。
ServiceControl的init方法简单的调用所有已注册的MBean的init方法来完成初始化。
ServiceControl的start方法简单的调用所有已注册的MBean的start方法来完成启动。
DefaultDomain:service=Webserver :org.jboss.web.WebService
DefaultDomain:service=Naming :org.jboss.naming.NamingService
DefaultDomain:service=JNDIView :org.jboss.naming.JNDIView
DefaultDomain:service=TransactionManager :
org.jboss.tm.TransactionManagerService
org.jboss.tm.plugins.tyrex.TransactionManagerService
DefaultDomain:service=ClientUserTransaction :org.jboss.tm.usertx.server.ClientUserTransactionService
DefaultDomain:service=JaasSecurityManager :org.jboss.security.plugins.JaasSecurityManagerService
DefaultDomain:service=JdbcProvider :org.jboss.jdbc.JdbcProvider
DefaultDomain:service=Hypersonic :org.jboss.jdbc.HypersonicDatabase
XADataSource:service=DefaultDS :org.jboss.jdbc.XADataSourceLoader
Management:service=Collector :org.jboss.management.ServerDataCollector
:service=ContainerFactory :org.jboss.ejb.ContainerFactory
DefaultDomain:service=EmbeddedTomcat:
org.jboss.web.catalina.EmbeddedCatalinaServiceSX
DefaultDomain:service=Jetty:
JBossMQ:service=Server: org.jboss.mq.server.JBossMQService
JBossMQ:service=StateManager: org.jboss.mq.server.StateManager
JBossMQ:service=PersistenceManager: org.jboss.mq.pm.rollinglogged.PersistenceManager
JBossMQ:service=InvocationLayer,type=JVM:
org.jboss.mq.il.jvm.JVMServerILService
JBossMQ:service=InvocationLayer,type=RMI:
org.jboss.mq.il.rmi.RMIServerILService
JBossMQ:service=InvocationLayer,type=OIL:
org.jboss.mq.il.oil.OILServerILService
JBossMQ:service=InvocationLayer,type=UIL:
org.jboss.mq.il.uil.UILServerILService
JBossMQ:service=Topic,name=testTopic:
org.jboss.mq.server.TopicManager
JBossMQ:service=Topic,name=example:
org.jboss.mq.server.TopicManager
JBossMQ:service=Topic,name=bob:
org.jboss.mq.server.TopicManager
JBossMQ:service=Queue,name=DLQ:
org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=testQueue:
org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=controlQueue:
org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=A:
org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=B:
org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=C:
org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=D:
org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=E:
org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=F:
org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=ex:
org.jboss.mq.server.QueueManager
为了向后兼容所引入的MBean
DefaultDomain:service=NamingAlias,fromName=QueueConnectionFactory:
org.jboss.naming.NamingAlias
DefaultDomain:service=NamingAlias,fromName=TopicConnectionFactory:
org.jboss.naming.NamingAlias
消息驱动MBean
:service=JMSProviderLoader,name=JBossMQProvider
org.jboss.jms.jndi.JMSProviderLoader
:service=ServerSessionPoolMBean,name=StdJMSPool:
org.jboss.jms.asf.ServerSessionPoolLoader
J2EE:service=J2eeDeployer:
org.jboss.deployment.J2eeDeployer
J2EE:service=J2eeDeployer(optional):
org.jboss.deployment.scope.J2eeGlobalScopeDeployer
JCA:service=RARDeployer:
org.jboss.resource.RARDeployer
JCA:service=ConnectionManagerFactoryLoader,name=MinervaNoTransCMFactory:
org.jboss.resource.ConnectionManagerFactoryLoader
JCA:service=ConnectionManagerFactoryLoader,name=MinervaSharedLocalCMFactory:
org.jboss.resource.ConnectionManagerFactoryLoader
JCA:service=ConnectionManagerFactoryLoader,name=MinervaXACMFactory:
org.jboss.resource.ConnectionManagerFactoryLoader
JCA:service=ConnectionFactoryLoader,name=MinervaDS:
org.jboss.resource.ConnectionFactoryLoader
resource adapter example
DefaultDomain:service=RawXADataSourceLoader,name=MinervaXADS
org.jboss.jdbc.RawXADataSourceLoader
JCA:service=ConnectionFactoryLoader,name=XAMinervaDS:
org.jboss.resource.ConnectionFactoryLoader
JMS XA Resource adapter
JCA:service=ConnectionFactoryLoader,name=JmsXA:
org.jboss.resource.ConnectionFactoryLoader
EJB:service=AutoDeployer:
org.jboss.ejb.AutoDeployer
Adaptor:name=RMI
org.jboss.jmx.server.JMXAdaptorService
Connector:name=RMI:
org.jboss.jmx.server.RMIConnectorService
Adaptor:name=html:
com.sun.jdmk.comm.HtmlAdaptorServer
:service=Mail
org.jboss.mail.MailService
Monitor:name=BeanCacheMonitor:
org.jboss.monitor.BeanCacheMonitor
:service=Scheduler:
org.jboss.util.Scheduler
检查是否符合MBean规范(参考JMX笔记内省算法)
meta.testCompliance(theClass);
如果对象实现了MBeanRegistration接口,调用其preRegisterInvoker方法
if (object instanceof MBeanRegistration) {
res=preRegisterInvoker(object,name);
}
把对象加入池中
internal_addObject(object, logicalName);
如果对象实现了MBeanRegistration接口,调用其postRegisterInvoker方法
if (object instanceof MBeanRegistration)
postRegisterInvoker(object, true);
如果新注册的MBean是一个类加载器,把它加在加载器池中
if (object instanceof ClassLoader) {
DefaultLoaderRepository.addClassLoader((ClassLoader)object);
}
如果是动态MBean,获取其MBeanInfo和ClassName
MBeanInfo mbi = ((DynamicMBean)object).getMBeanInfo();
className = mbi.getClassName();
返回ObjectInstance对象以供使用
return(new ObjectInstance(logicalName, className));
public Object invoke(ObjectName name, String operationName, Object params[],
String signature[])
throws InstanceNotFoundException, MBeanException, ReflectionException;
取得MBean对象的实例
Object obj = getMBean(name);
取得MBean的接口
Class mbeanClass = meta.getMBeanInterface(instance.getClass());
在注册时曾经用meta检查对象的接口,在检查的时候,meta把对象的MBeanInterface保存在自己的mbeanInterfaceCache中,现在可以从中取回。如果对象是DynamicMBean,则meta不会保存,返回null。
用指定的类装载器重新装载参数
Class primCla = meta.findClassForPrim(signature[i]);
params[i]= transferObject(params[i], aloader);
查找将要启动的方法
Method mth= meta.findMethod(mbeanClass, operationName, tab);
启动方法
result= mth.invoke(instance, params);