How Tomcat Work 之 第十七章:Tomcat Startup
来源:互联网 发布:聚丙烯看盘软件下载 编辑:程序博客网 时间:2024/06/02 20:20
回顾
这章主要讲Tomcat的启动,使用到两个类分别是:Catalina和Bootstrap。Catalina类用于启动和停止一个服务器对象也解析Tomcat的配置文件,server.xml。Bootstrap类用于创建Catalina实例并调用其处理方法。理论上,这两个类已经合并了。然而,为支持更多的模式运行Tomcat,提供了大量的Bootstrap类。例如,上面提及的Bootstrap类用于单独的应用运行Tomcat。另一个类,BootstrapService,作为Windows NT Service来运行Tomcat。
为了用户方便,Tomcat也提供批量文件和shell脚本来开启和停止容器。在这些批量文件和shell脚本的帮助下,用户不需要去记java.exe程序的选项来运行Bootstrap类。而选择运行适量的批量文件或者shell脚本。
这章的第一部分讨论了Catalina类,第二部分讨论了Bootstrap类。只有认真理解了第十四章的server和Service,第十五章的Digester,第十六章的shutdown hooks,才能很好地理解本章的内容。这章也讨论了如何在windows/linux上运行Tomcat。一部分致力于批量文件启动和停止Window的Tomcat。另一部分讲述了Unix/Linux的shell脚本。
The Catalian class
org.apache.catalina.startup.Catalina类是一个启动类。它包含了一个Digester来解析%CATALINE_HOME%/conf目录下的server.xml文件。理解了添加到这个Digester的规则,你可以根据你所想的来配置你的Tomcat。
Catalian类也封装了一个Server对象,其有一个Service。就如第十五章中提到的,一个Service对象包含了一个容器和一个或者更多的连接器。你使用Catalian启动和停止这个服务器对象。
实例化这个Catalian类来运行Tomcat并稍后调用其处理方法。当调用这个方法的时候必须传递合适的参数。如果你想启动Tomcat,第一个参数是start,如果想发送一个shutdown命令来停止 参数就是stop。也有其他可接受的参数,比如-help,-config,-debug,和-nonaming。
注意:ninaming参数,如果存在,指定JNDI命名是不应该支持的。查看org.apache.naming包获取更多的信息关于JNDI命名如何支持Tomcat。
一般地,你需要一个Bootstrap类来实例化Catalian并调用其处理方法,即使Catalian类有一个main方法提供了一个入口点。Bootstap类其中一个在下一节中讲述。你也将在这一节中知道Bootstarp做了什么。
Tomcat 4中的Catalian的处理方法的代码清单如下:
public void process(String args[]) { setCatalinaHome(); setCatalinaBase(); try { if (arguments(args)) execute(); } catch (Exception e) { e.printStackTrace(System.out); }}
process方法设置了两个系统属性,catalina.home和catalian.base.catalina.home,其是user.dir属性的默认值。catalina.base属性指定为catalina.home的值。因此,两个属性有usr.dir属性的值。
注意,urer.dir系统属性涉及到用户的工作目录,即,调用Java命令的目录。为查看系统属性列表,查看java.lang.System的getProperties方法。
process方法之后调用arguments方法,传递参数列表。arguments方法,代码清单17.2如下,处理命令行参数,如果catalina对象应该继续执行返回true。
protected boolean arguments(String args[]) { boolean isConfig = false; if (args.length < 1) { usage(); return (false); } for (int i = 0; i < args.length; i++) { if (isConfig) { configFile = args[i]; isConfig = false; } else if (args[i].equals("-config")) { isConfig = true; } else if (args[i].equals("-debug")) { debug = true; } else if (args[i].equals("-nonaming")) { useNaming = false; } else if (args[i].equals("-help")) { usage(); return (false); } else if (args[i].equals("start")) { starting = true; } else if (args[i].equals("stop")) { stopping = true; } else { usage(); return (false); } } return (true);}
process方法演示了arguments方法的返回值并且如果arguments方法返回true调用execute方法。此方法的代码清单17.3如下:
protected void execute() throws Exception { if (starting) start(); else if (stopping) stop();}
execute方法要不调用start方法启动Tomcat,要不调用stop方法停止Tomcat。这两个方法在下一节中讨论。
注意:在Tomcat 5中,不再有execute方法。start或者stop方法由process方法直接调用。
The start Method
start方法创建了一个Digester实例来处理server.xml方法(Tomcat的配置文件)。在解析XML文件之前,start方法调用Digester的push方法,来解析当前Catalian对象。这样Catalian对象将是Digester内部对象栈中的第一个对象。parsing 将导致一个Server变量引用一个Server对象,默认地是org.apache.catalian.core.StandardServer类型。start方法将稍后调用Server对象的intialize方法和start方法。Catalian的start方法稍后继续通过调用Server对象的await方法,导致Server对象来指定一个线程来等待一个shutdown命令。await方法不会返回直到接受到一个关闭命令。当await方法返回的时候,Catalina的start方法调用服务器对象的stop方法,将停止服务器对象和所有其他的组件。start方法也将布置一个shutdown 钩子确保用户突然退出的时候,服务器对象的stop方法理应执行。
start方法的代码清单如下:
protected void start() { // Create and execute our Digester Digester digester = createStartDigester(); File file = configFile(); try { InputSource is =new InputSource("file://" + file.getAbsolutePath()); FileInputStream fis = new FileInputStream(file); is.setByteStream(fis); digester.push(this); digester.parse(is); fis.close(); } catch (Exception e) { System.out.println("Catalina.start: " + e); e.printstackTrace(System.out); System.exit(1); } // Setting additional variables if (!useNaming) { System.setProperty("catalina.useNaming", "false"); } else { System.setProperty("catalina.useNaming", "true"); String value = "org.apache.naming"; String oldValue =System.getProperty(javax.naming.Context.URL_PKG_PREFIXES); if (oldValue != null) { value = value + ":" + oldValue; } System.setProperty(javax.naming.Context.URL_PKG_PREFIXES, value); value = System.getProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY); if (value == null) { System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY,"org.apache.naming.java.javaURLContextFactory"); } } // If a SecurityManager is being used, set properties for // checkPackageAccess() and checkPackageDefinition if( System.getSecurityManager() != null ) { String access = Security.getProperty("package.access"); if( access != null && access.length() > 0 ) access += ","; else access = "sun.,"; Security.setProperty("package.access",access + "org.apache.catalina.,org.apache.jasper."); String definition = Security.getProperty("package.definition"); if( definition != null && definition.length() > 0 ) definition += ","; else definition = "sun.,"; Security.setProperty("package.definition",definition + "java.,org.apache.catalina.,org.apache.jasper."); } // Replace System.out and System.err with a custom PrintStream SystemLogHandler log = new SystemLogHandler(System.out); System.setOut(log); System.setErr(log); Thread shutdownHook = new CatalinaShutdownHook(); // Start the new server if (server instanceof Lifecycle) { try { server.initialize(); ((Lifecycle) server).start(); try { // Register shutdown hook Runtime.getRuntime().addShutdownHook(shutdownHook); } catch (Throwable t) { // This will fail on JDK 1.2. Ignoring, as Tomcat can run // fine without the shutdown hook. } // Wait for the server to be told to shut down server.await(); } catch (LifecycleException e) { System.out.println("Catalina.start: " + e); e.printStackTrace(System.out); if (e.getThrowable() != null) { System.out.println("----- Root Cause -----"); e.getThrowable().printStackTrace(System.out); } } } // Shut down the server if (server instanceof Lifecycle) { try { try { // Remove the ShutdownHook first so that server.stop() // doesn't get invoked twice Runtime.getRuntime().removeShutdownHook(shutdownHook); } catch (Throwable t) { // This will fail on JDK 1.2. Ignoring, as Tomcat can run // fine without the shutdown hook. } ((Lifecycle) server).stop(); } catch (LifecycleException e) { System.out.println("Catalina.stop: " + e); e.printStackTrace(System.out); if (e.getThrowable() != null) { System.out.println("----- Root Cause -----"); e.getThrowable().printStackTrace(System.out); } } }}
The stop Method
stop方法停止Catalina和导致Server对象关闭。代码清单如下:
protected void stop() { // Create and execute our Digester Digester digester = createStopDigester(); File file = configFile(); try { InputSource is =new InputSource("file://" + file.getAbsolutePath()); FileInputStream fis = new FileInputStream(file); is.setByteStream(fis); digester.push(this); digester.parse(is); fis.close(); } catch (Exception e) { System.out.println("Catalina.stop: " + e); e.printStackTrace(System.out); System.exit(1); } // Stop the existing server try { Socket socket = new Socket("127.0.0.1", server.getPort()); OutputStream stream = socket.getoutputStream(); String shutdown = server.getShutdown(); for (int i = 0; i < shutdown.length(); i++) stream.write(shutdown.charAt(i)); stream.flush(); stream.close(); socket.close(); } catch (IOException e) { System.out.println("Catalina.stop: " + e); e.printStackTrace(System.out); System.exit(1); }}
注意:stop方法调用createStopDigester方法创建了一个Digester实例,通过调用Digester的push方法将当前Catalina对象放入Digester的内部栈中并解析配置文件。关于添加到Digester的规则在“Stop Digester”章节中讨论。
stop方法发送一条关闭命令来停止运行的服务器对象。
- How Tomcat Work 之 第十七章:Tomcat Startup
- How Tomcat work 之第十四章之service
- How Tomcat work 之第十五章之Digester
- How Tomcat Work 之 第十六章 之 ShutDown Hook
- how tomcat work之第十四章:server and service
- How Tomcat Work 之Digester之The Applicaition
- How tomcat work 之 第十五章之Digester之ContextConfig之the defaultConfig Method
- How Tomcat work 之第十四章之server and services 之application
- How Tomcat work之第十五章之Digester之setting property
- How do I make Tomcat startup faster?
- tomcat 之startup.bat文件
- tomcat简单实现(how tomcat work第一章内容)
- how does startup code work
- TOMCAT 之 startup.bat文件分析
- How tomcat work读书笔记 chapter2 a simple servlet
- tomcat startup.bat解读
- tomcat startup.bat解读
- tomcat startup.bat 解读
- hdu 4333 Revolving Digits
- poj2411
- 模板,大数相加
- eclipse中默认js编辑器非常慢,尤其在拷贝粘贴代码时的解决方法
- C# 改变窗体中所有TextBox控件的属性
- How Tomcat Work 之 第十七章:Tomcat Startup
- 怎么得到斐波那契数列?(m*n大小的矩形,从左上角走到左下角有多少种走法?包括一些引申题以及总结)
- HDU - 2066 一个人的旅行 (Dijkstra)
- UVA10815 Andy's First Dictionary
- 为什么要用Struts2?
- uva10306 - e-Coins(记忆化搜索)
- Populating Next Right Pointers in Each Node II (LeetCode)
- Python实现的解析网页看报程序
- HDU1715大数相加