关闭钩子
?
预览
很多情况下,当应用程序被用户关闭时候,此应用程序都需要获得执行收尾工作程序的机会。但是问题是,用户并不总是按着推荐的方式执行关闭操作。例如,在 Tomcat部署中,你通过初始化一个 Server 并且启动它而启动整个 servlet 容器,然后通过发送正常的关闭指令来关闭此 Server ,而 Server 收到这个关闭指令时会执行 stop 方法运行收尾工作。但是总会有一些程序突然中断这种例外发生,比如用户直接关闭了此 Tomcat 运行的控制台。
幸运的是,Java 为程序员提供了一种优雅的方式来执行关闭过程中的代码,这可以确保你的收尾代码总是会被执行。本章展示了怎么使用关闭构造来确保无论 Java 应用程序是怎么被用户关闭它的收尾工作总是会被执行
Java中,虚拟机会根据两种事件来关闭它自己:
?? 当System.exit() 方法被执行或最后一个非守护线程退出时,它会正常关闭自己。
?? 用户对虚拟机控制台的突然关闭,比如在控制台上按下CTRL+C 或在未退出虚拟机的情况下突然退出当前操作系统。
关闭虚拟机时,虚拟机会按照下列两个步骤退出:
?? 虚拟机调用所有的已注册关闭钩子,关闭钩子是在之前程序中注册入Runtime 的线程。这些关闭构造线程的运行时同步的。
?? 如果可能的话,虚拟机会调用所有未被调用的清理器(Object.finalize()? )
在本章中,我们主要关注的是第一步,因为它可以运行程序员告诉虚拟机需要做哪些收尾工作。关闭钩子是一个简单的java.lang.Thread 子类实例。创建一个关闭构造也是很简单的:
?? 写一个类并让此类继承自Thread 类(实现 Runable 接口应该也可)
?? 提供此类的run 方法实现。此 run 方法中的代码就是在应用程序关闭时需要执行的代码,无聊是正常关闭还是突然关闭。
?? 在应用程序中实例化此类。
?? 使用此类实例调用Runtime 的 addShutdownHook 方法注册关闭钩子
也许你已经注意到了,我们并没有像其他线程一样显式的调用这个线程的start 方法。因为虚拟机会在运行到关闭这一步时启动并且运行这个关闭构造线程。
?
(中间部分略,很简单,木意思)
?
Tomcat中关闭钩子的应用
就像你想象的那样,Tomcat 在它内部配备了一个关闭钩子。你可以在 org.apache.catalina.startup.Catalina 类中找到它(它是一个内部类)。此 Catalina 类为管理其他组件的 Server 对象的启动负责。它内部有一个叫做 CatalinaShutdownHook 的类,此类继承自 java.lang.Thread 类,它的 run 方法调用了 Server 对象的 stop 方法:
protected class CatalinaShutdownHook extends Thread { public void run() { if (server != null) { try { ((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); } } } } }?
我们可以看到,在Catalina 启动阶段中,此方法构造了一个关闭钩子并且将此钩子注册入 Runtime 中,关于此 Catalina 类你会在第十七章中了解到更多。
?
?
总结:
有时我们需要在应用关闭执行一些收尾工作,但是我们也不能总是依赖于用户的正常关闭程序。本章讨论的关闭钩子提供了一个解决办法,它可以确保无论用户怎么关闭当前应用而收尾代码一定会被执行的。
?
===================================================================
第十七章:Tomcat的启动
本章重点关注 Tomcat用于启动的 org.apache.catalina.startup 包中的两个类: Catalina 和 Bootstrap 。 Catalina 用来启动和终止 Server 对象并且解析 Tomcat 的配置文件 server.xml 。 Bootstrap 类顾名思义是一个引导类,作为整个应用程序的切入点,它创建一个 Catalina 对象并且调用它的 process 方法。理论上来说,这两个类应该结合为一个类的。然而,为了支持多种多样的 Tomcat 启动方式, Tomcat 必须提供不止一个的引导类。例如,前述的 Bootstrap 类把 Tomcat 当做独立的应用程序来运行,而另外的一个类, org.apache.catalina.startup.BootstrapService ,它可以将 Tomcat 运行为一个 Windows 中的服务进程。
为了使用的方便性,Tomcat 也提供了二进制文件和 shell 脚本来使 servlet 容器的启动和终止变得简单。使用这些二进制文件和 shell 脚本的帮助,用户不需要使用 java.exe 来运行 Bootstrap 类,只需要运行合适的二进制文件或 shell 脚本即可。
本章的第一节会讨论一下Catalina 类,然后第二节会讨论一下 Bootstrap 类。如果想理解本章讨论的核心,你必须确保你已经读过了第十四章(服务器和服务)、第十五章(解析器 Digester )、第十六章(关闭钩子)。本章也分了两小节来讨论怎么在 Windows 和 Unix/Linux 下运行 Tomcat 。一个小节专门用来讨论在 Windows 下启动和终止 Tomcat 的二进制文件,另一章解释了用于 Unix/Linux 下的 shell 脚本。
但是、关于Windows和Linux/Unix不同平台下的脚本等,由于脚本语言学的不好,且感觉这些已经偏出了Tomcat内部运行机制的范畴。略过
?
==================================================================
第十八章:Deployer
??? 由于时间关系、本章没有深入、了解的也不深。它是与Tomcat的应用部署有关,于是就有点忽视了。
最近快期末考试了、就先放一放
?
===================================================================
第十九章:管理Servlet
其实就是讲了一个Tomcat自带的管理内部已部署的应用的默认应用。很简单、也不想看。也木有时间
===================================================================
?
第二十章感觉有点难度啊、讲到了JMX与Tomcat之间的种种亲密关系。感觉如果想深入的话、没有几天是不可能的啊、但是时间宝贵、就先放一放了
?
母老鼠、表再让哥挂科了