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 ...
随机推荐
- readLine() 和 "\r","\n" 问题
很多输入流中都有一个函数readLine(),我们也经常使用这个函数,但有时如果不认真考虑,这个函数也会带来一些小麻烦. 如果我们是从控制台读入的话,我们也许没有想过readLine函数到底是根据&q ...
- Tomcat服务器(一)
一.tomcat目录中重要的文件: bin 存放启动和关闭的脚本 conf 存放配置文件 logs 日志文件 webapps 存放部署的项目 work 工作目录 Web应用开发好后,若想供外界访问, ...
- kafka不停止服务的情况下修改日志保留时间
kafka配置文件如下: broker.id=1 port=9092 host.name=ssy-kafka1 num.network.threads=4 num.io.threads=8 socke ...
- Easy Ui 的reload 问题
当我删除某条数据时,删除成功后要刷新datagrid 这时调用reload方法就不成功,而要用下面的方式. 正确代码$('#fixedGrid').datagrid("reload" ...
- ASP.NET Web API 2.0 统一响应格式
传统实现 在搭建 Web API 服务的时候,针对客户端请求,我们一般都会自定义响应的 JSON 格式,比如: { "Data" : { "Id" : 100, ...
- SQL 取两日期的记录
SELECT TOP 1000 [ID] ,[SourcePageID] ,[PlatformType] ,[CreateTime] FROM [home_sendor ...
- .net Framework使用之 MongoDB
新建Helper using MongoDB.Bson; using MongoDB.Driver; using System; using System.Collections.Generic; u ...
- Linq to SQL 参考Demo
LINQ to SQL语句()之Where Where操作 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句 ...
- Hbuilder系列索引
『原创』手把手教你搭建一个实用的油耗App(一)
- Vue 进阶之路(十)
之前的文章介绍了 vue 的组件化,本章我们来看一下 vue 中组件的原生事件. <!DOCTYPE html> <html lang="en"> < ...