目錄
- 靜態代碼塊
- main()方法
- init()方法
- initClassLoaders()方法
- load()方法
- start()方法
上一章,我們下載原始碼,并啟動了原始碼,Tomcat原始碼分析(一)啟動Tomcat原始碼 ,
現在,我們來看看Bootstrap啟動類做了些什么作業,
靜態代碼塊
設定了catelina.home和catalina.base
點擊查看代碼
static {
// Will always be non-null
// 當前作業目錄的路徑,總是不會為null
String userDir = System.getProperty("user.dir");
// Home first
String home = System.getProperty(Constants.CATALINA_HOME_PROP);
File homeFile = null;
if (home != null) {
File f = new File(home);
try {
homeFile = f.getCanonicalFile();
} catch (IOException ioe) {
homeFile = f.getAbsoluteFile();
}
}
if (homeFile == null) {
// First fall-back. See if current directory is a bin directory
// in a normal Tomcat install
File bootstrapJar = new File(userDir, "bootstrap.jar");
if (bootstrapJar.exists()) {
File f = new File(userDir, "..");
try {
homeFile = f.getCanonicalFile();
} catch (IOException ioe) {
homeFile = f.getAbsoluteFile();
}
}
}
if (homeFile == null) {
// Second fall-back. Use current directory
File f = new File(userDir);
try {
homeFile = f.getCanonicalFile();
} catch (IOException ioe) {
homeFile = f.getAbsoluteFile();
}
}
catalinaHomeFile = homeFile;
// 設定了catelina.home
System.setProperty(Constants.CATALINA_HOME_PROP, catalinaHomeFile.getPath());
// Then base
String base = System.getProperty(Constants.CATALINA_BASE_PROP);
if (base == null) {
catalinaBaseFile = catalinaHomeFile;
} else {
File baseFile = new File(base);
try {
baseFile = baseFile.getCanonicalFile();
} catch (IOException ioe) {
baseFile = baseFile.getAbsoluteFile();
}
catalinaBaseFile = baseFile;
}
// 設定了catalina.base
System.setProperty(Constants.CATALINA_BASE_PROP, catalinaBaseFile.getPath());
}
main()方法
1.加鎖新建一個Bootstrap物件,呼叫init初始化并且賦值給了私有靜態物件daemon
2.呼叫了daemon物件load和start方法,而load和start方法里面利用了反射呼叫了catalinaDeamon的load和start方法
點擊查看代碼
/**
* Main method and entry point when starting Tomcat via the provided
* scripts.
*
* @param args Command line arguments to be processed
*/
public static void main(String args[]) {
synchronized (daemonLock) {
if (daemon == null) {
// Don't set daemon until init() has completed
Bootstrap bootstrap = new Bootstrap();
try {
bootstrap.init();
} catch (Throwable t) {
handleThrowable(t);
t.printStackTrace();
return;
}
daemon = bootstrap;
} else {
// When running as a service the call to stop will be on a new
// thread so make sure the correct class loader is used to
// prevent a range of class not found exceptions.
Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
}
}
try {
String command = "start";
if (args.length > 0) {
command = args[args.length - 1];
}
if (command.equals("startd")) {
args[args.length - 1] = "start";
daemon.load(args);
daemon.start();
} else if (command.equals("stopd")) {
args[args.length - 1] = "stop";
daemon.stop();
} else if (command.equals("start")) {
daemon.setAwait(true);
daemon.load(args);
daemon.start();
if (null == daemon.getServer()) {
System.exit(1);
}
} else if (command.equals("stop")) {
daemon.stopServer(args);
} else if (command.equals("configtest")) {
daemon.load(args);
if (null == daemon.getServer()) {
System.exit(1);
}
System.exit(0);
} else {
log.warn("Bootstrap: command \"" + command + "\" does not exist.");
}
} catch (Throwable t) {
// Unwrap the Exception for clearer error reporting
if (t instanceof InvocationTargetException &&
t.getCause() != null) {
t = t.getCause();
}
handleThrowable(t);
t.printStackTrace();
System.exit(1);
}
}
init()方法
1.使用initClassLoaders()創建了commonLoader、catalinaLoader和sharedLoader
2.利用反射新建一個org.apache.catalina.startup.Catalina類物件,賦值給了catalinaDeamon,
點擊查看代碼
/**
* Initialize daemon.
* @throws Exception Fatal initialization error
*/
public void init() throws Exception {
initClassLoaders();
Thread.currentThread().setContextClassLoader(catalinaLoader);
SecurityClassLoad.securityClassLoad(catalinaLoader);
// Load our startup class and call its process() method
// 加載啟動類并呼叫其process()方法
if (log.isDebugEnabled()) {
log.debug("Loading startup class");
}
Class<?> startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
Object startupInstance = startupClass.getConstructor().newInstance();
// Set the shared extensions class loader
if (log.isDebugEnabled()) {
log.debug("Setting startup class properties");
}
String methodName = "setParentClassLoader";
Class<?> paramTypes[] = new Class[1];
paramTypes[0] = Class.forName("java.lang.ClassLoader");
Object paramValues[] = new Object[1];
paramValues[0] = sharedLoader;
Method method =
startupInstance.getClass().getMethod(methodName, paramTypes);
method.invoke(startupInstance, paramValues);
catalinaDaemon = startupInstance;
}
initClassLoaders()方法
創建了commonLoader、catalinaLoader和sharedLoader
點擊查看代碼
private void initClassLoaders() {
try {
commonLoader = createClassLoader("common", null);
if (commonLoader == null) {
// no config file, default to this loader - we might be in a 'single' env.
commonLoader = this.getClass().getClassLoader();
}
catalinaLoader = createClassLoader("server", commonLoader);
sharedLoader = createClassLoader("shared", commonLoader);
} catch (Throwable t) {
handleThrowable(t);
log.error("Class loader creation threw exception", t);
System.exit(1);
}
}
load()方法
通過反射呼叫catalinaDaemon的load()方法
點擊查看代碼
/**
* Load daemon.
*/
private void load(String[] arguments) throws Exception {
// Call the load() method
String methodName = "load";
Object param[];
Class<?> paramTypes[];
if (arguments==null || arguments.length==0) {
paramTypes = null;
param = null;
} else {
paramTypes = new Class[1];
paramTypes[0] = arguments.getClass();
param = new Object[1];
param[0] = arguments;
}
Method method =
catalinaDaemon.getClass().getMethod(methodName, paramTypes);
if (log.isDebugEnabled()) {
log.debug("Calling startup class " + method);
}
method.invoke(catalinaDaemon, param);
}
start()方法
通過反射呼叫catalinaDaemon的start()方法
點擊查看代碼
/**
* Start the Catalina daemon.
* @throws Exception Fatal start error
*/
public void start() throws Exception {
if (catalinaDaemon == null) {
init();
}
Method method = catalinaDaemon.getClass().getMethod("start", (Class [])null);
method.invoke(catalinaDaemon, (Object [])null);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/458604.html
標籤:Java
