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 ...
随机推荐
- MFC-CWinApp
概览 CWinApp为应用程序类, CWinApp由 CWinThread 派生而来 ,后者表示可能具有一个或多个线程的应用程序的主执行线程,基于框架生成的应用程序必须有且仅有一个从 CWinApp ...
- Hibernate和spring中的session总结
1.this.getSession() 是org.springframework.orm.hibernate3.support.HibernateDaoSupport 中的一个方法,它可以从当前事务或 ...
- UniGui之锱铢积累(仔细看这个文件)
http://www.doc88.com/p-4022977294324.html 这个是Word文档
- CSS 温故而知新
如何让文字垂直居中 需要设置div的height,line-height 为一样的值,如下所示: <div class="ui-bar ui-bar-e" style=&qu ...
- SSH 安全建议
当你查看你的 SSH 服务日志,可能你会发现充斥着一些不怀好意的尝试性登录.这里有 5 条常规建议(和一些个别特殊策略)可以让你的 OpenSSH 会话更加安全. 强化密码登录 密码登录很方便,因为你 ...
- ASP.NET Web API 2.0 统一响应格式
传统实现 在搭建 Web API 服务的时候,针对客户端请求,我们一般都会自定义响应的 JSON 格式,比如: { "Data" : { "Id" : 100, ...
- NET 下载共享文件
执行 public static void Run() { "); if (state) { // 共享文件夹的目录 TransportRemoteToLocal(@"\\192. ...
- 关于Unity中的NavMeshAgent的remainingDistance问题
Unity中的NavMeshAgent的remainingDistance问题 在Unity官方案例中,要让某个人物移动到某个地方,一般来说都是下面这样的代码: agent.SetDestinatio ...
- leetcode 第三大的数
给定一个非空数组,返回此数组中第三大的数.如果不存在,则返回数组中最大的数.要求算法时间复杂度必须是O(n). 示例 1: 输入: [3, 2, 1] 输出: 1 解释: 第三大的数是 1. 示例 2 ...
- Redis持久化————AOF与RDB模式
1. 官方说明: By default Redis asynchronously dumps the dataset on disk. This mode is good enou ...