Tomcat Server之启动---Bootstrap类

Tomcat虽然作为轻量级的Web Server,但是其设计精巧,作为一个Server,方方面面的知识都有涉及。今天我们就来研究一下他的启动类Bootstrap。

一、Class Bootstrap

  Bootstrap类作为程序的入口自然是main(),而跟Bootstrap启动类相关的有:

  ClassLoaderFactory : 负责创建类加载器。

  SecurityClassLoad : 负责加载已经编译好的整个Server的class文件。

  CatalinaProperties: 作为属性加载器,读取整个Server的系统属性,也读取同包中的Catalina.Properties的属性

  可以看出,Bootstrap类启动的方式可以说就是创建类加载器,加载Server 的class文件。

-----------------------------------------------------------------------

二、具体实现

  首先是-----------Variables----------

 1 public final class Bootstrap {
 2 
 3     private static final Log log = LogFactory.getLog(Bootstrap.class);
 4     private static Bootstrap daemon = null;
    //文件路径
5 private static final File catalinaBaseFile; 6 private static final File catalinaHomeFile; 7 private static final Pattern PATH_PATTERN = Pattern.compile("(\".*?\")|(([^,])*)"); 8 private Object catalinaDaemon = null;
    //类加载器
9 ClassLoader commonLoader = null; 10 ClassLoader catalinaLoader = null; 11 ClassLoader sharedLoader = null;

  静态语句块static{...}对常量catalinaBaseFile,catalinaHomeFile进行了赋值操作。

 1 static {
 2         String userDir = System.getProperty("user.dir"); userDir="D:\IdeaProject\tomcatmini"
 3         String home = System.getProperty("catalina.home"); home=null
 4         File homeFile = null;
 5         File f;
 6         if (home != null) {
 7             f = new File(home);
 8 
 9             try {
10                 homeFile = f.getCanonicalFile();
11             } catch (IOException var9) {
12                 homeFile = f.getAbsoluteFile();
13             }
14         }
15 
16         File baseFile;
17         if (homeFile == null) { homeFile = null
18             f = new File(userDir, "bootstrap.jar");
19             if (f.exists()) {
20                 baseFile = new File(userDir, "..");
21 
22                 try {
23                     homeFile = baseFile.getCanonicalFile();
24                 } catch (IOException var8) {
25                     homeFile = baseFile.getAbsoluteFile();
26                 }
27             }
28         }
29 
30         if (homeFile == null) { homeFile = null进入此分支,
31             f = new File(userDir);
32 
33             try {
34                 homeFile = f.getCanonicalFile();
35             } catch (IOException var7) {
36                 homeFile = f.getAbsoluteFile(); homeFile = "D:\IdeaProject\tomcatmini"
37             }
38         }
39 
40         catalinaHomeFile = homeFile;
41         System.setProperty("catalina.home", catalinaHomeFile.getPath());
42         String base = System.getProperty("catalina.base"); base = null
43         if (base == null) {
44             catalinaBaseFile = catalinaHomeFile; catalinaBaseFile = "D:\IdeaProject\tomcatmini" 
45         } else {
46             baseFile = new File(base);
47 
48             try {
49                 baseFile = baseFile.getCanonicalFile();
50             } catch (IOException var6) {
51                 baseFile = baseFile.getAbsoluteFile();
52             }
53 
54             catalinaBaseFile = baseFile;
55         }
56 
57         System.setProperty("catalina.base", catalinaBaseFile.getPath());
58     }

然后是-----------main()-----------

 

 1 public static void main(String[] args) {
 2         if (daemon == null) { daemon == null
 3             Bootstrap bootstrap = new Bootstrap();
 4 
 5             try {
 6                 bootstrap.init(); 点此init可以超链接哦
 7             } catch (Throwable var3) {
 8                  handleThrowable(var3);
 9                 var3.printStackTrace();
10                 return;
11             }
12 
13             daemon = bootstrap;
14         } else {
15             Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
16         }
17 
18         try {
19             String command = "start";
20             if (args.length > 0) {
21                 command = args[args.length - 1];
22             }
23 
24             if (command.equals("startd")) {
25                 args[args.length - 1] = "start";
26                 daemon.load(args);
27                 daemon.start();
28             } else if (command.equals("stopd")) {
29                 args[args.length - 1] = "stop";
30                 daemon.stop();
31             } else if (command.equals("start")) {
32                 daemon.setAwait(true);
33                 daemon.load(args);
34                 daemon.start();
35             } else if (command.equals("stop")) {
36                 daemon.stopServer(args);
37             } else if (command.equals("configtest")) {
38                 daemon.load(args);
39                 if (null == daemon.getServer()) {
40                     System.exit(1);
41                 }
42 
43                 System.exit(0);
44             } else {
45                 log.warn("Bootstrap: command \"" + command + "\" does not exist.");
46             }
47         } catch (Throwable var4) {
48             Throwable t = var4;
49             if (var4 instanceof InvocationTargetException && var4.getCause() != null) {
50                 t = var4.getCause();
51             }
52 
53             handleThrowable(t);
54             t.printStackTrace();
55             System.exit(1);
56         }
57 
58     }

 ----------------------init()----------------------

    public void init() throws Exception {  此方法内部创建类加载器和安全加载相关类文件还有设置setContextClassLoader
        this.initClassLoaders(); 初始化类加载器
        Thread.currentThread().setContextClassLoader(this.catalinaLoader); 设置当前线程为ContextClassLoader
        SecurityClassLoad.securityClassLoad(this.catalinaLoader); catalinaLoader作为类加载器加载去加载catalina服务器core,session,util等文件。
        if (log.isDebugEnabled()) {
            log.debug("Loading startup class");
        }

        Class<?> startupClass = this.catalinaLoader.loadClass("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;
    }

  

-----------initClassLoaders-------------

    private void initClassLoaders() {
        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);
        }

    }

  -------

    private ClassLoader createClassLoader(String name, ClassLoader parent) throws Exception {
        String value = CatalinaProperties.getProperty(name + ".loader");
        System.out.println(value);
        if (value != null && !value.equals("")) {
            value = this.replace(value);
            List<ClassLoaderFactory.Repository> repositories = new ArrayList();
            String[] repositoryPaths = getPaths(value);
            String[] arr$ = repositoryPaths;
            int len$ = repositoryPaths.length;

            for(int i$ = 0; i$ < len$; ++i$) {
                String repository = arr$[i$];

                try {
                    new URL(repository);
                    repositories.add(new ClassLoaderFactory.Repository(repository, ClassLoaderFactory.RepositoryType.URL));
                } catch (MalformedURLException var11) {
                    if (repository.endsWith("*.jar")) {
                        repository = repository.substring(0, repository.length() - "*.jar".length());
                        repositories.add(new ClassLoaderFactory.Repository(repository, ClassLoaderFactory.RepositoryType.GLOB));
                    } else if (repository.endsWith(".jar")) {
                        repositories.add(new ClassLoaderFactory.Repository(repository, ClassLoaderFactory.RepositoryType.JAR));
                    } else {
                        repositories.add(new ClassLoaderFactory.Repository(repository, ClassLoaderFactory.RepositoryType.DIR));
                    }
                }
            }

            return ClassLoaderFactory.createClassLoader(repositories, parent);
        } else {
            return parent;
        }
    }

  -----------------------

 

posted on 2017-12-23 18:13  剑姬  阅读(1743)  评论(0编辑  收藏  举报

导航