Tomcat学习之启动过程
来源:互联网 发布:个人可以注册cn域名吗 编辑:程序博客网 时间:2024/05/20 16:35
http://blog.csdn.net/aesop_wubo/article/details/7610904
startup.bat
当我们启动tomcat一般是运行%TOMCAT_HOME%\bin\startup.bat文件,这个文件实际上调用了%TOMCAT_HOME%\bin\catalina.bat批处理文件:
- set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat"
- ......
- set CMD_LINE_ARGS=
- :setArgs
- if ""%1""=="""" goto doneSetArgs
- set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
- shift
- goto setArgs
- :doneSetArgs
- call "%EXECUTABLE%" start %CMD_LINE_ARGS%
- %_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %JPDA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
_EXECJAVA=_RUNJAVA="%JRE_HOME%\bin\java",这是在%TOMCAT_HOME%\bin\setclasspath.bat文件中设置的,也就是说这句要运行一个JAVA程序,后面紧接着就应该是运行的类%MAINCLASS%,MAINCLASS=org.apache.catalina.startup.Bootstrap,不错org.apache.catalina.startup.Bootstrap类正是Tomcat的入口类,Tomcat正是从Bootstrap类的main方法开始运行的。
Bootstrap
下面来看看Bootstrap的main方法做了哪些事情:
- public static void main(String args[]) {
- if (daemon == null) {
- Bootstrap bootstrap = new Bootstrap();
- try {
- bootstrap.init();
- } catch (Throwable t) {
- handleThrowable(t);
- t.printStackTrace();
- return;
- }
- daemon = bootstrap;
- }
- try {
- ...
- if (command.equals("start"))
- daemon.start();
- ...
- } catch (Throwable t) {
- ...
- }
- }
1、初始化;
2、装配tomcat容器
3、启动tomcat容器
初始化
- public void init()
- throws Exception
- {
- // Set Catalina path
- setCatalinaHome();
- setCatalinaBase();
- initClassLoaders();
- Thread.currentThread().setContextClassLoader(catalinaLoader);
- SecurityClassLoad.securityClassLoad(catalinaLoader);
- // Load our startup class and call its process() method
- if (log.isDebugEnabled())
- log.debug("Loading startup class");
- Class<?> startupClass =
- catalinaLoader.loadClass
- ("org.apache.catalina.startup.Catalina");
- Object startupInstance = startupClass.newInstance();
- // Set the shared extensions class loader
- if (log.isDebugEnabled())
- log.debug("Setting startup class properties");
- String methodName = "setParentClassLoader";
- Class<?> paramTypes[] = new Class[1];
- paramTypes[0] = Class.forName("java.lang.ClassLoader");
- Object paramValues[] = new Object[1];
- paramValues[0] = sharedLoader;
- Method method =
- startupInstance.getClass().getMethod(methodName, paramTypes);
- method.invoke(startupInstance, paramValues);
- catalinaDaemon = startupInstance;
- }
如果catalina.home被设置过直接返回,否则设置:如果bootstrap.jar文件存在,就设置为这个文件所在目录的上一级目录;如果不存在就设置为当前工作目录。在%TOMCAT_HOME%\bin目录下实际上是有这个jar文件的,也就是catalina.home=%TOMCAT_HOME%。
2、设置catalina.base系统属性,和1差不多
3、initClassLoaders,初始化三个classLoader:
commonLoader:用于加载common/lib目录下的jar包和class文件
catalinaLoader:用于加载server/lib目录下的jar包和class文件
sharedLoader:用于加载shared/lib目录下的jar包和class文件
catalinaLoader:用于加载server/lib目录下的jar包和class文件
sharedLoader:用于加载shared/lib目录下的jar包和class文件
commonLoader是catalinaLoader和sharedLoader的parent classloader,Tomcat6以后,查看catalina.properties文件可以看见server.loader和shared.loader都是为空的。
catalina.properties文件中common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar
4、然后设置当前线程的classloader为catalinaLoader
5、紧接着加载与安全相关的包和类
6、然后设置org.apache.catalina.startup.Catalina这个类的parent classloader为sharedLoader
7、创建org.apache.catalina.startup.Catalina这个类的实例并赋给catalinaDaemon
装配容器
通过调用org.apache.catalina.startup.Catalina的load方法来实现的
- public void load() {
- initDirs();
- // Before digester - it may be needed
- initNaming();
- // Create and execute our Digester
- Digester digester = createStartDigester();
- digester.push(this);
- digester.parse(inputSource);
- getServer().init();
- }
- }
2、创建一个digester对象,解析conf/server.xml文件,在解析server.xml的过程中会调用StandardService.setContainer方法,将其设置为StandardEngine
3、初始化Servlet窗口,这里的getServer()实际上返回的是StandardServer对象,这个初始化过程是在StandardServer类的initInternal方法中完成的,这个方法主要干了两件事,1是注册MBean,让JMX管理tomat容器,2是初始化Service
- // Initialize our defined Services
- for (int i = 0; i < services.length; i++) {
- services[i].init();
- }
- protected void initInternal() throws LifecycleException {
- if (container != null) {
- container.init();
- }
- // Initialize any Executors
- for (Executor executor : findExecutors()) {
- if (executor instanceof LifecycleMBeanBase) {
- ((LifecycleMBeanBase) executor).setDomain(getDomain());
- }
- executor.init();
- }
- // Initialize our defined Connectors
- synchronized (connectors) {
- for (Connector connector : connectors) {
- connector.init();
- }
- }
- }
这个方法也做了几件事,1是初始化container,会调用StandardEngine的initInternal方法,2初始化Executor,3是初始化两个连接器[Connector[HTTP/1.1-8080], Connector[AJP/1.3-8009]]
启动容器
此处的start调用的是org.apache.catalina.startup的start方法
- public void start() {
- ...
- long t1 = System.nanoTime();
- // Start the new server
- try {
- getServer().start();
- } catch (LifecycleException e) {
- log.error("Catalina.start: ", e);
- }
- ...
- if (await) {
- await();
- stop();
- }
- }
start方法会调用StandardServer、StandardService、StandardEngine、StandardHost、StandardContext、StandardWrapper的start或者startInternal方法来完成启动过程,最后会循环等待,在关闭命令到来之前一直运行!
总结
1、tomcat中大量引入了模板方法模式,org.apache.catalina.util.LifecycleBase被所有容器继承,其中initInternal和startInternal方法是抽象方法,在初始化和启动时被每个容器会调用其init和start方法,这两个方法会去调用对应抽象方法***Internal,这些抽象方法都是在子类中实现的
2、tomcat中大量使用了类的反射,基本上都是通过配置文件获取类名,然后利用反射得到class对象,再通过newInstance获取对象。
0 0
- Tomcat学习之启动过程
- Tomcat学习之启动过程
- Tomcat学习之启动过程
- Tomcat 学习进阶历程之Tomcat启动过程分析
- tomcat源码学习2------启动过程
- Tomcat源码阅读之Engine启动过程
- 解读tomcat源码之tomcat的启动过程
- tomcat启动过程
- Tomcat的启动过程
- Tomcat的启动过程
- tomcat 启动过程
- Tomcat启动过程分析
- Tomcat启动过程
- tomcat的启动过程
- Tomcat启动过程
- Tomcat启动过程详解
- tomcat的启动过程
- Tomcat启动过程分析
- baidumap
- 2016年7月24日完成任务
- 织梦DedeCms通过.htaccess禁止指定IP或IP段访问
- 织梦DedeCms网站更换域名后文章图片路径批量修改
- 自定义View二
- Tomcat学习之启动过程
- 心态
- 织梦DedeCms系统未审核文档禁止动态浏览修改方法
- java中string与byte[]的转换
- 通过IIS7 Rewrite完美实现织梦DedeCms 301重定向
- 给织梦DedeCms文章页加上百度、谷歌搜索本篇文章功能
- Tomcat学习之Acceptor
- POJ 2686 - Y2K Accounting Bug
- 在织梦DedeCms的搜索框里显示提示信息