tomcat启动(二)org.apache.catalina.startup.Bootstrap分析
/**
* 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分析的更多相关文章
- IDEA tomcat启动异常 org.apache.catalina.startup.ContextConfig parseWebXml
启动Tomcat发现有异常,总是无法启动,具体的异常日志为下图 具体的解决方法为:在tomcat的conf/content.xml中加上<Loader delegate="true&q ...
- 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 ...
- tomcat启动 报org.apache.catalina.LifecycleException异常
java 服务器 tomcat启动 报org.apache.catalina.LifecycleException异常 异常代码如下: [2018-05-10 04:45:08,856] Artifa ...
- Could not find the main class: org.apache.catalina.startup.Bootstrap. Program will exit.
出现此异常原因是jdk环境变量未配置正确
- 启动Tomcat服务时,出现org.apache.catalina.startup.VersionLoggerListener报错
启动Tomcat服务时,出现org.apache.catalina.startup.VersionLoggerListener报错解决办法:打开Tomcat安装后目录,进入conf文件夹,找到配置文件 ...
- 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 问题原因 主要原 ...
- 现网环境业务不影响,但是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 ...
- Tomcat无法启动:org.apache.catalina.LifecycleException: Failed to start component 问题解决
问题如下:需要使用到数据库mysql,于是将mysql-connector-java-5.1.30-bin.jar的数据库驱动复制到WEE-INF/lib目录下.点击运行,但是服务器无法启动. 控制台 ...
- java.lang.ClassNotFoundException: org.apache.catalina.startup.VersionLoggerListener
解决办法 找到Tomcat配置文件server.xml apache-tomcat-7.0.57/conf 将<Listener className="org.apache.cat ...
随机推荐
- ACM STEPS——Chapter Two——Section One
数学题小关,做得很悲剧,有几道题要查数学书... 记下几道有价值的题吧 The area(hdoj 1071) http://acm.hdu.edu.cn/showproblem.php?pid=10 ...
- Ansible基本命令
Ansible安装完成之后就自带很多命令,其中较常用的有7个: ansible ansible-doc ansible-galaxy ansible-init ansible-playbook ans ...
- java实现WC项目
个人项目:WC wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数.单 ...
- [笔记]学习EBS建议有的知识
http://f.dataguru.cn/thread-51057-1-1.html ORACLE EBS学习的其他资源有哪四个? ORACLE OPEN WORLD大会是不是一个市场营销活动? Or ...
- Android-Android/APP-理解
Android 1.Google Android 给出的官方Android架构图就是大家都知道的四层,第一层是应用层(就是很多能够看得到的应用),第二层是应用框架层(为application提 供各种 ...
- 笔记本U盘安装CentOS 7
1. 下载镜像,制作U盘安装盘,设置BIOS启动等内容网上有大量的文章,本文不再赘述. 2. 开机U盘启动后会看到这样的界面: 3. 笔记本安装CentOS最容易出问题的地方在于USB安装盘的选择,如 ...
- 使用Postman验证TFS Rest API
概述 你可能已经了解到,TFS自2015版本发布以来,开始支持通过REST API的方式提供接口服务,第三方平台可以通过通用的HTTP协议访问TFS系统,获取数据.请求编译等.REST API在原有. ...
- 设计模式之状态模式(State Pattern)
一.什么是状态模式? 把所有动作都封装在状态对象中,状态持有者将行为委托给当前状态对象 也就是说,状态持有者(比如汽车,电视,ATM机都有多个状态)并不知道动作细节,状态持有者只关心自己当前所处的状态 ...
- char、varchar、nchar、nvarchar特点比较
于程序中的string型字段,SQLServer中有char.varchar.nchar.nvarchar四种类型来对应(暂时不考虑text和ntext),开建立数据库中,对这四种类型往往比较模糊,这 ...
- ARM 编译工具keil 和 IAR 命令行编译和下载
目的 不管是Keil还是IAR对代码补全,高亮等编辑功能支持的不是很好,虽然现在的Keil 5.25对界面的支持好了很多,但是很多人还是青睐于第三方的编辑器,命令行的编译方式可以让我们在使用第三方编辑 ...