private static Bootstrap daemon = null; 如果没有,这初始化
调用BootStrap中的init方法:
1.this.initClassLoaders();
: if deamon==null
初始化Bootstrap接着调用Bootstrap的init方法:
this.initClassLoaders(),初始化三个类加载器commonLoader,
catalinaLoader,sharedLoader。其中commonLoader加载器可以读取
common/classes,common/endorsed,common/lib目录下的Java类,
catalinaLoader负责加载server/lib,/server/classes,sharedLoader
负责加载/shared/classes,/shared/lib。其中commonLoader,是
catalinaLoader,sharedLoader父类加载器。让deamon=t;
try {
this.commonLoader = this.createClassLoader("common", (ClassLoader)null);
if(this.commonLoader == null) {
this.commonLoader = this.getClass().getClassLoader();
}
this.catalinaLoader = this.createClassLoader("server", this.commonLoader);
this.sharedLoader = this.createClassLoader("shared", this.commonLoader);
} catch (Throwable var2) {
handleThrowable(var2);
log.error("Class loader creation threw exception", var2);
System.exit(1);
}
else
Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);//线程上下文切换器
2.调用catalinaLodader加载器加载org.apache.catalina.startup.Catalina,并完成初始化
获取该类当中的setParentClassLoader方法调用ClassLoader,将sharedLoader放入。
this.catalinaDaemon=this.catalinaLoader.loadClass("org.apache.catalina.startup.Catalina").startupClass.newInstance();
this.initClassLoaders();
Thread.currentThread().setContextClassLoader(this.catalinaLoader);
SecurityClassLoad.securityClassLoad(this.catalinaLoader);
if(log.isDebugEnabled()) {
log.debug("Loading startup class");
}
Class startupClass = this.catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
Object startupInstance = startupClass.newInstance();
if(log.isDebugEnabled()) {
log.debug("Setting startup class properties");
}
String methodName = "setParentClassLoader";
Class[] paramTypes = new Class[]{Class.forName("java.lang.ClassLoader")};
Object[] paramValues = new Object[]{this.sharedLoader};
Method method = startupInstance.getClass().getMethod(methodName, paramTypes);
method.invoke(startupInstance, paramValues);
this.catalinaDaemon = startupInstance;
3.判断启动参数和停止参数
try {
String t2 = "start";
if(args.length > 0) {
t2 = args[args.length - 1];
}
if(t2.equals("startd")) {
args[args.length - 1] = "start";
daemon.load(args);
daemon.start();
} else if(t2.equals("stopd")) {
args[args.length - 1] = "stop";
daemon.stop();
} else if(t2.equals("start")) {
daemon.setAwait(true);
daemon.load(args);
daemon.start();
} else if(t2.equals("stop")) {
daemon.stopServer(args);
} else if(t2.equals("configtest")) {
daemon.load(args);
if(null == daemon.getServer()) {
System.exit(1);
}
System.exit(0);
} else {
log.warn("Bootstrap: command \"" + t2 + "\" does not exist.");
}
4.
3 中的load方法
Method method = this.catalinaDaemon.getClass().getMethod(methodName, paramTypes); //方法名,调用参数
调用org.apache.catalina.startup.Catalina中的load方法:
method.invoke(this.catalinaDaemon, param);
3.1 创建Digester 类
使用digester映射JavaBean和xml
3.2 加载配置文件 conf/server.xml
转化为inputSource
没有配置文件,则log.debug(sm.getString("catalina.configFail", new Object[]{file}), var25);
加载conf/server.xml server-embed.xml
将该类加入到digester栈顶digester.push(this);,解析 digester.parse(inputSource); xml文件
label251: {
try {
try {
file = this.configFile();
inputStream = new FileInputStream(file);
inputSource = new InputSource(file.toURI().toURL().toString());
} catch (Exception var25) {
if(log.isDebugEnabled()) {
log.debug(sm.getString("catalina.configFail", new Object[]{file}), var25);
}
}
if(inputStream == null) {
try {
inputStream = this.getClass().getClassLoader().getResourceAsStream(this.getConfigFile());
inputSource = new InputSource(this.getClass().getClassLoader().getResource(this.getConfigFile()).toString());
} catch (Exception var26) {
if(log.isDebugEnabled()) {
log.debug(sm.getString("catalina.configFail", new Object[]{this.getConfigFile()}), var26);
}
}
}
if(inputStream == null) {
try {
inputStream = this.getClass().getClassLoader().getResourceAsStream("server-embed.xml");
inputSource = new InputSource(this.getClass().getClassLoader().getResource("server-embed.xml").toString());
} catch (Exception var27) {
if(log.isDebugEnabled()) {
log.debug(sm.getString("catalina.configFail", new Object[]{"server-embed.xml"}), var27);
}
}
}
if(inputStream != null && inputSource != null) {
try {
inputSource.setByteStream((InputStream)inputStream);
digester.push(this);
digester.parse(inputSource);
break label251;
} catch (SAXParseException var28) {
log.warn("Catalina.start using " + this.getConfigFile() + ": " + var28.getMessage());
return;
} catch (Exception var29) {
log.warn("Catalina.start using " + this.getConfigFile() + ": ", var29);
return;
}
}
关闭IO流
3.3.调用Server方法
this.getServer().setCatalina(this);
this.getServer().setCatalinaHome(Bootstrap.getCatalinaHomeFile());
this.getServer().setCatalinaBase(Bootstrap.getCatalinaBaseFile());
3.3.1 初始化StandardServer类 server,并传入值
this.initStreams();
this.getServer().init(); //初始化生命周期
3.3.1 this.getServer().init()
public interface Lifecycle void init() throws LifecycleException;
其实现类:
this.setStateInternal(LifecycleState.INITIALIZING, (Object)null, false); //设置生命周期状态
this.initInternal();
this.setStateInternal(LifecycleState.INITIALIZED, (Object)null, false)
load完成
4.start
获取加载器
4.1 this.initClassLoaders();
Thread.currentThread().setContextClassLoader(this.catalinaLoader);
SecurityClassLoad.securityClassLoad(this.catalinaLoader);
if(log.isDebugEnabled()) {
log.debug("Loading startup class");
}
//调用方法父类加载器
Class startupClass = this.catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
Object startupInstance = startupClass.newInstance();
if(log.isDebugEnabled()) {
log.debug("Setting startup class properties");
}
String methodName = "setParentClassLoader";
Class[] paramTypes = new Class[]{Class.forName("java.lang.ClassLoader")};
Object[] paramValues = new Object[]{this.sharedLoader};
Method method = startupInstance.getClass().getMethod(methodName, paramTypes);
method.invoke(startupInstance, paramValues);
this.catalinaDaemon = startupInstance;
4.2 调用映射
Method method = this.catalinaDaemon.getClass().getMethod("start", (Class[])null);
method.invoke(this.catalinaDaemon, (Object[])null);
调用Catalina.start()
if(this.getServer() == null) {
this.load();
}
4.2.1 调用生命周期中的start()方法
4.2.2 创建钩子程序
if(this.shutdownHook == null) {
this.shutdownHook = new Catalina.CatalinaShutdownHook();
}
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
LogManager logManager = LogManager.getLogManager();
if(logManager instanceof ClassLoaderLogManager) {
((ClassLoaderLogManager)logManager).setUseShutdownHook(false);
}
4.2.3 唤醒,停止
if(this.await) {
this.await();
this.stop();
}
4.2.3.1 关闭过程
try {
this.awaitThread = Thread.currentThread();
while(!this.stopAwait) {
try {
Thread.sleep(10000L);
} catch (InterruptedException var64) {
;
}
}
} finally {
this.awaitThread = null;
}
} else {
try {
this.awaitSocket = new ServerSocket(this.port, 1, InetAddress.getByName(this.address));
} catch (IOException var67) {
log.error("StandardServer.await: create[" + this.address + ":" + this.port + "]: ", var67);
return;
}
boolean var32 = false;
ServerSocket serverSocket;
try {
var32 = true;
this.awaitThread = Thread.currentThread();
while(true) {
if(this.stopAwait) {
var32 = false;
break;
}
serverSocket = this.awaitSocket;
if(serverSocket == null) {
var32 = false;
break;
}
Socket socket = null;
StringBuilder command = new StringBuilder();
label615: {
label614: {
try {
label638: {
long acceptStartTime = System.currentTimeMillis();
InputStream match;
try {
socket = serverSocket.accept();
socket.setSoTimeout(10000);
match = socket.getInputStream();
} catch (SocketTimeoutException var69) {
log.warn(sm.getString("standardServer.accept.timeout", new Object[]{Long.valueOf(System.currentTimeMillis() - acceptStartTime)}), var69);
continue;
} catch (AccessControlException var70) {
log.warn("StandardServer.accept security exception: " + var70.getMessage(), var70);
continue;
} catch (IOException var71) {
if(this.stopAwait) {
break label614;
}
log.error("StandardServer.await: accept: ", var71);
break label638;
}
int expected;
for(expected = 1024; expected < this.shutdown.length(); expected += this.random.nextInt() % 1024) {
if(this.random == null) {
this.random = new Random();
}
}
while(true) {
if(expected <= 0) {
break label615;
}
boolean ch = true;
int var75;
try {
var75 = match.read();
} catch (IOException var66) {
log.warn("StandardServer.await: read: ", var66);
var75 = -1;
}
if(var75 < 32 || var75 == 127) {
break label615;
}
command.append((char)var75);
--expected;
}
}
} finally {
try {
if(socket != null) {
socket.close();
}
} catch (IOException var63) {
;
}
}
var32 = false;
break;
}
var32 = false;
break;
}
boolean var74 = command.toString().equals(this.shutdown);
if(var74) {
log.info(sm.getString("standardServer.shutdownViaPort"));
var32 = false;
break;
}
log.warn("StandardServer.await: Invalid command \'" + command.toString() + "\' received");
}
} finally {
if(var32) {
ServerSocket serverSocket1 = this.awaitSocket;
this.awaitThread = null;
this.awaitSocket = null;
if(serverSocket1 != null) {
try {
serverSocket1.close();
} catch (IOException var62) {
;
}
}
}
}
serverSocket = this.awaitSocket;
this.awaitThread = null;
this.awaitSocket = null;
if(serverSocket != null) {
try {
serverSocket.close();
} catch (IOException var65) {
;
}
}
}
关闭过程相当于在启动中创建一个线程等待,等到发送关闭命令以后Socket捕获这个线程然后启动关闭
程序。
4.2.3.2 关闭钩子程序
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
LogManager e = LogManager.getLogManager();
if(e instanceof ClassLoaderLogManager) {
((ClassLoaderLogManager)e).setUseShutdownHook(true);
}
}