分析Server的步骤
关于分析Server自然不能是全文把每一个函数都看一遍,具体的分析思路是根据执行步骤去按照逻辑的顺序来一点一点分析。所以其实分析Server应该从之前讲的catlina的执行流程中开始分析。
在讲解catlina的时候其中说过Server.init()。但是在Server接口中其实是没有定义init(),这个方法其实是在它的父类接口中定义的。而init()的实际操作其实是在他的实现类中StandardServer.initInternal(),至于为什么是initInternal而不是init(),这是相关的代码
LifecycleBase.init()
@Override
public final synchronized void init() throws LifecycleException {
if (!state.equals(LifecycleState.NEW)) {
invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
}
try {
setStateInternal(LifecycleState.INITIALIZING, null, false);
initInternal();
setStateInternal(LifecycleState.INITIALIZED, null, false);
} catch (Throwable t) {
handleSubClassException(t, "lifecycleBase.initFail", toString());
}
}
也就是说调用init(),实质上是在调用initInternal,至于为啥是在LifecycleBase中定义,是由于LifecycleBase是Lifecycle的默认实现类,而Lifecycle其实是tomcat中来定义生命周期的一个接口。(Lifecycle相关的知识会专门写一个博客的)
而关于start方法其实也是一样的,相关的操作也是在StandardServer.startInternal中。
所以就开始分析StandardServer这个类吧。
StandServer.initInternal
@Override
protected void initInternal() throws LifecycleException {
super.initInternal();
// Register global String cache
// Note although the cache is global, if there are multiple Servers
// present in the JVM (may happen when embedding) then the same cache
// will be registered under multiple names
onameStringCache = register(new StringCache(), "type=StringCache");
// Register the MBeanFactory
MBeanFactory factory = new MBeanFactory();
factory.setContainer(this);
onameMBeanFactory = register(factory, "type=MBeanFactory");
// Register the naming resources
globalNamingResources.init();
// Populate the extension validator with JARs from common and shared
// class loaders
if (getCatalina() != null) {
ClassLoader cl = getCatalina().getParentClassLoader();
// Walk the class loader hierarchy. Stop at the system class loader.
// This will add the shared (if present) and common class loaders
while (cl != null && cl != ClassLoader.getSystemClassLoader()) {
if (cl instanceof URLClassLoader) {
URL[] urls = ((URLClassLoader) cl).getURLs();
for (URL url : urls) {
if (url.getProtocol().equals("file")) {
try {
File f = new File (url.toURI());
if (f.isFile() &&
f.getName().endsWith(".jar")) {
ExtensionValidator.addSystemResource(f);
}
} catch (URISyntaxException | IOException e) {
// Ignore
}
}
}
}
cl = cl.getParent();
}
}
// Initialize our defined Services
for (Service service : services) {
service.init();
}
}
1,对父类的初始化
@Override
protected void initInternal() throws LifecycleException {
// If oname is not null then registration has already happened via
// preRegister().
if (oname == null) {
mserver = Registry.getRegistry(null, null).getMBeanServer();
oname = register(this, getObjectNameKeyProperties());
}
}
代码相对简单,其实就是对ManabedBean的进行一次注册。
2,注册全局的字符串缓存
3,注册MBeanFactory
4,globalNamingResources.init()
(用于注册资源的命名)
5,利用来自common和shared的类加载器的jars进行扩展校验
6,初始化service
(这才是重点,一个server可以初始化多个service,这部分也会单独拿出来分析)
注: Service:Service是包含Connector和Container的集合,Service用适当的Connector接收用户的请求,再发给相应的Container来处理。
关于Service,Connector和Container的相关知识后面都会有所介绍。
StandServer.startInternal()
@Override
protected void startInternal() throws LifecycleException {
fireLifecycleEvent(CONFIGURE_START_EVENT, null);
setState(LifecycleState.STARTING);
globalNamingResources.start();
// Start our defined Services
synchronized (servicesLock) {
for (Service service : services) {
service.start();
}
}
}
1,执行 fireLifecycleEvent函数
(这是一个处理lifecycleEvent时间的方法,在LifecycleBase中定义)
2,将状态设置为STARTING
3,globalNamingResources.start()
4,开始执行service
(也是server,start()的核心步骤)
由此对于 server的分析也就告一段落