/**
* Bootstrap loader for Catalina. This application constructs a class loader
* for use in loading the Catalina internal classes (by accumulating all of the
* JAR files found in the "server" directory under "catalina.home"), and
* starts the regular execution of the container. The purpose of this
* roundabout approach is to keep the Catalina internal classes (and any
* other classes they depend on, such as an XML parser) out of the system
* class path and therefore not visible to application level classes.

这个类构造一个类加载器来加载Catalina内部类(通过在server目录下的catalina.home来找到所有的jar文件),和开始定期执行container容器。

这种回旋处理方法的目的是保持Catalina内部类(以及其依赖的任何其他类,如XML解析器)脱离系统类路径,因此对应用程序级别不可见

入口main方法

在进入main之前会前执行static静态模块代码:主要是设置catalina.home和catalina.base的路径

public static void main(String args[]) {
bootstrap初始化init()
设置守护进程daemon = bootstrap;
识别启动bootstrap时传递的参数command = args[args.length - 1];//start
daemon.setAwait(true);
daemon.load(args);
daemon.start();}

上面damemon守护进程的方法setAwait(),load(),start()其实是反射调用的org.apache.catalina.startup.Catalina类的方法

到这里其实就进入到Catalina类的。

--------------------------Bootstrap类解析完毕------下面是对init方法解释---------------------------------------------------------

初始化init方法(初始化守护进程):

在这个方法里主要流程

1、初始化类加载器initClassLoaders()----------commonLoader,catalinaLoader,sharedLoade会先加载catalina.base/conf/catalina.propertises配置文件

然后读取common.loader键所对应的值

Catalina.properties文件下
common.loader="${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar"

补充下:

commonLoader再定义时使用ClassLoader定义,但是创建返回的是URLClassLoader。公有类定义,子类返回,这个思路值得借鉴

public class URLClassLoader extends SecureClassLoader implements Closeable

URLClassLoader继承SecureClassLoader

public class SecureClassLoader extends ClassLoader

SecureClassLoader继承ClassLoader

ClassLoader commonLoader = null;
ClassLoader catalinaLoader = null;
ClassLoader sharedLoader = null;

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);

createClassLoader()

获取common.loader键对应的值
String value = CatalinaProperties.getProperty(name + ".loader"); String[] repositoryPaths = getPaths(value);
。。。省略部分代码
for (String repository : repositoryPaths) {
// Check for a JAR URL repository
try {
@SuppressWarnings("unused")
URL url = new URL(repository);
repositories.add(
new Repository(repository, RepositoryType.URL));
continue;
} catch (MalformedURLException e) {
// Ignore
} // Local repository
if (repository.endsWith("*.jar")) {
repository = repository.substring
(0, repository.length() - "*.jar".length());
repositories.add(
new Repository(repository, RepositoryType.GLOB));
} else if (repository.endsWith(".jar")) {
repositories.add(
new Repository(repository, RepositoryType.JAR));
} else {
repositories.add(
new Repository(repository, RepositoryType.DIR));
}
}
return ClassLoaderFactory.createClassLoader(repositories, parent);最后调用这个方法将repositories内存放的类和资源的路径绑定到commonLoader。这里返回的是new URLClassLoader

createClassLoader()方法获取到

common.loader="${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar"

接下来会判断这个字符串是以什么结尾

${catalina.base}/lib
${catalina.home}/lib

/lib是目录 commonLoader会加载整个目录下的资源,包括所有clsss、jar包及其它类型资源

${catalina.base}/lib/*.jar
${catalina.home}/lib/*.jar

表示整个目录下所有jar包资源,仅仅是.jar后缀的资源

解释下RepositoryType这是一个枚举类型,定义再类org.apache.catalina.startup.ClassLoaderFactory内部

public static enum RepositoryType {
DIR,表示整个目录下的资源,包括所有clsss、jar包及其它类型资源。
GLOB,表示整个目录下所有jar包资源,仅仅是.jar后缀的资源。
JAR,表示单个jar包资源。
URL表示网络上得某个jar包资源
}

2、为当前线程设置classLoader

Thread.currentThread().setContextClassLoader(catalinaLoader);catalinaLoader其实就是commonLoader

用静态类SecurityClassLoad预加载类资源

SecurityClassLoad.securityClassLoad(catalinaLoader);

securityClassLoad(ClassLoader loader, boolean requireSecurityManager)  {   
。。。。。略。。。。。。。。。。
     loadCorePackage(loader);
loadCoyotePackage(loader);
loadLoaderPackage(loader);
loadRealmPackage(loader);
loadServletsPackage(loader);
loadSessionPackage(loader);
loadUtilPackage(loader);
loadValvesPackage(loader);
loadWebResourcesPackage(loader);
loadJavaxPackage(loader);
loadConnectorPackage(loader);
loadTomcatPackage(loader);
}

3、初始化org.apache.catalina.startup.Catalina利用反射调用它的setParentClassLoader设置sharedLoader;(设置的parentClassLoader的原因和用处暂不完全清楚,看源码估计会在server.xml加载部分会使用到)

参考资源

Tomcat内核之类加载器工厂

具体源码解析:http://blog.csdn.net/u011545486/article/details/52002626

tomcat启动(二)org.apache.catalina.startup.Bootstrap分析的更多相关文章

  1. IDEA tomcat启动异常 org.apache.catalina.startup.ContextConfig parseWebXml

    启动Tomcat发现有异常,总是无法启动,具体的异常日志为下图 具体的解决方法为:在tomcat的conf/content.xml中加上<Loader delegate="true&q ...

  2. Tomcat7.0 start Could not find the main class: org.apache.catalina.startup.Bootstrap.

    java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory at org.apache.catalina.startup.Bo ...

  3. tomcat启动 报org.apache.catalina.LifecycleException异常

    java 服务器 tomcat启动 报org.apache.catalina.LifecycleException异常 异常代码如下: [2018-05-10 04:45:08,856] Artifa ...

  4. Could not find the main class: org.apache.catalina.startup.Bootstrap. Program will exit.

    出现此异常原因是jdk环境变量未配置正确

  5. 启动Tomcat服务时,出现org.apache.catalina.startup.VersionLoggerListener报错

    启动Tomcat服务时,出现org.apache.catalina.startup.VersionLoggerListener报错解决办法:打开Tomcat安装后目录,进入conf文件夹,找到配置文件 ...

  6. MyEclipse启动Tomcat报错:Could not find the main class: org.apache.catalina.startup

    问题描述 Could not find the main class:org.apache.catalina.startup.Bootstrap. Program will exit 问题原因 主要原 ...

  7. 现网环境业务不影响,但是tomcat启动一直有error日志,ERROR org.apache.catalina.startup.ContextConfig- Unable to process Jar entry [module-info.class] from Jar [jar:file:/home/iufs/apache-tomcat/webapps/iufs/WEB-INF/lib/asm

    完整的错误日志信息: 2019-03-19 15:30:42,021 [main] INFO org.apache.catalina.core.StandardEngine- Starting Ser ...

  8. Tomcat无法启动:org.apache.catalina.LifecycleException: Failed to start component 问题解决

    问题如下:需要使用到数据库mysql,于是将mysql-connector-java-5.1.30-bin.jar的数据库驱动复制到WEE-INF/lib目录下.点击运行,但是服务器无法启动. 控制台 ...

  9. java.lang.ClassNotFoundException: org.apache.catalina.startup.VersionLoggerListener

    解决办法 找到Tomcat配置文件server.xml   apache-tomcat-7.0.57/conf 将<Listener className="org.apache.cat ...

随机推荐

  1. (连通图 Tarjan)Caocao's Bridges --HDU --4738

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=4738 题目大意:曹操有很多岛屿,然后呢需要建造一些桥梁将所有的岛屿链接起来,周瑜要做的是就是不让曹操将所 ...

  2. ZOJ2482 IP Address 2017-04-18 23:11 44人阅读 评论(0) 收藏

    IP Address Time Limit: 2 Seconds      Memory Limit: 65536 KB Suppose you are reading byte streams fr ...

  3. android 热更新nuwa

    简介 Nuwa是比较流行的一种Android热补丁方案的开源实现,它的特点是成功率高,实现简单.当然,热补丁的方案目前已经有很多了,AndFix, Dexposed, Tinker等,之所以要分析Nu ...

  4. Linux下的ICMP反弹后门:PRISM

    搜索的时候无意中看见的这款基于ping的ICMP后门.于是到作者的github上看看,居然是阴文的,为了过级,只能强忍着看了,学生狗伤不起.还好比较简单易懂,正如简介说的一样:“PRISM is an ...

  5. jsp ckeditor ckfinder

    我认为对的事情,有可能是完全错的. 这篇教程很好: http://www.cnblogs.com/yuepeng/archive/2013/04/01/2992097.html 只看到9,权限控制还没 ...

  6. Need You Now --Lady Antebellum

    战地女神(Lady Antebellum)由女主唱 Hillary Scott.男主唱 Charles Kelley .吉他/键盘手 Dave Haywood,2006夏天在美国乡村音乐重镇纳什维尔组 ...

  7. flume 整合kafka

    背景:系统的数据量越来越大,日志不能再简单的文件的保存,如此日志将会越来越大,也不方便查找与分析,综合考虑下使用了flume来收集日志,收集日志后向kafka传递消息,下面给出具体的配置 # The ...

  8. Android中设置分割线

    设置分隔线的方法一: 在需要设置分隔线的布局文件中加入如下代码: <View     android:layout_width="fill_parent"      andr ...

  9. Jersey构建Restful风格的Webserivces(三)

    一.总体说明 通过jersey-client接口,创建客户端程序,来调用Jersey实现的RESTful服务,实现增.删.改.查等操作. 服务端主要是通过内存的方式,来模拟用户的增加.删除.修改.查询 ...

  10. 对php和java里面的static函数和static的一些理解

    static function: "static方法就是没有this的方法.在static方法里面不可以调用非静态方法,反过来是可以的.并且可以在没有创建任何对象的前提下,仅仅通过类名来调用 ...