免费商城网站建设平台,商城建站模板,然后做网站,中式建筑网站本文主要目的是自定义举例分析Catalina内部生命周期管理的运作方式以及拿内部具体源码来具体分析 假设我们有一台电脑由主机(我们用cpu表示#xff09;和显示器构成#xff0c;那么我们要运用上篇文章学到的内容#xff0c;来管理整个电脑的启动和关闭#xff0c;先看我们对…本文主要目的是自定义举例分析Catalina内部生命周期管理的运作方式以及拿内部具体源码来具体分析 假设我们有一台电脑由主机(我们用cpu表示和显示器构成那么我们要运用上篇文章学到的内容来管理整个电脑的启动和关闭先看我们对类的定义。 在本例中我们对Lifecycle类进行了部分删减只保留了关于start和stop的相关事件。 Lifecycle public interface Lifecycle {// ----------------------------------------------------- Manifest Constantspublic static final String START_EVENT start;/*** The LifecycleEvent type for the component before start event.*/public static final String BEFORE_START_EVENT before_start;/*** The LifecycleEvent type for the component after start event.*/public static final String AFTER_START_EVENT after_start;/*** The LifecycleEvent type for the component stop event.*/public static final String STOP_EVENT stop;/*** The LifecycleEvent type for the component before stop event.*/public static final String BEFORE_STOP_EVENT before_stop;/*** The LifecycleEvent type for the component after stop event.*/public static final String AFTER_STOP_EVENT after_stop;// --------------------------------------------------------- Public Methodspublic void addLifecycleListener(LifecycleListener listener);public LifecycleListener[] findLifecycleListeners();public void removeLifecycleListener(LifecycleListener listener);public void start() throws LifecycleException;public void stop() throws LifecycleException;}同样LifecycleBase类也只保留了start,stop相关方法。 LifecycleBase public abstract class LifeCycleBase implements Lifecycle {private LifecycleSupport support new LifecycleSupport(this);//组件名称public String name;Overridepublic void addLifecycleListener(LifecycleListener listener) {support.addLifecycleListener(listener);}Overridepublic LifecycleListener[] findLifecycleListeners() {return support.findLifecycleListeners();}Overridepublic void removeLifecycleListener(LifecycleListener listener) {support.removeLifecycleListener(listener);}protected void fireLifecycleEvent(String type, Object data) {support.fireLifecycleEvent(type, data);}protected abstract void startInternal() throws LifecycleException;Overridepublic void start() throws LifecycleException {System.out.println(name 准备启动);fireLifecycleEvent(Lifecycle.BEFORE_START_EVENT, null);System.out.println(name 正在启动);fireLifecycleEvent(Lifecycle.START_EVENT, null);startInternal();System.out.println(name 启动完毕);fireLifecycleEvent(Lifecycle.AFTER_START_EVENT, null);}protected abstract void stopInternal() throws LifecycleException;Overridepublic void stop() throws LifecycleException {System.out.println(name 准备关闭);fireLifecycleEvent(Lifecycle.BEFORE_STOP_EVENT, null);System.out.println(name 正在关闭);stopInternal();fireLifecycleEvent(Lifecycle.STOP_EVENT, null);System.out.println(name 关闭完毕);fireLifecycleEvent(Lifecycle.AFTER_STOP_EVENT, null);}}电脑组成部件 CPU定义 CPU public class CPU extends LifeCycleBase {Overridepublic void startInternal() throws LifecycleException {System.out.println(super.name 在启动过程中 负载达到了100%!);}Overridepublic void stopInternal() throws LifecycleException {System.out.println(name 在关闭过程中 负载下降到了1%!);}public CPU(String name) {super.name name;}}电脑组成部件 Monitor定义 Monitor public class Monitor extends LifeCycleBase {Overridepublic void startInternal() throws LifecycleException {System.out.println(name 在启动过程中 屏幕 很亮);}Overridepublic void stopInternal() throws LifecycleException {System.out.println(name 在关闭过程中 屏幕渐渐暗了下去);}public Monitor(String name) {super.name name;}}电脑类的定义 Computer public class Computer extends LifeCycleBase {private CPU cpu ;private Monitor monitor;Overridepublic void startInternal() throws LifecycleException {System.out.println(name 在启动过程中 需要先启动子组件);if (cpu ! null) {((Lifecycle) cpu).start();}if (monitor ! null) {((Lifecycle) monitor).start();}}Overridepublic void stopInternal() throws LifecycleException {System.out.println(name 在关闭过程中 需要先关闭子组件);if (cpu ! null) {((Lifecycle) cpu).stop();}if (monitor ! null) {((Lifecycle) monitor).stop();}}public Computer(String name) {super.name name;}public void setCpu(CPU cpu) {this.cpu cpu;}public void setMonitor(Monitor monitor) {this.monitor monitor;}}运行类代码 public class MainClass {public static void main(String[] args) throws Exception {Computer computer new Computer(电脑);CPU cpu new CPU(CPU);Monitor monitor new Monitor(显示器);computer.setCpu(cpu);computer.setMonitor(monitor);cpu.addLifecycleListener(new LifecycleListener() {Overridepublic void lifecycleEvent(LifecycleEvent event) {if (event.getType().equals(Lifecycle.BEFORE_START_EVENT)) {System.out.println(已经监听到 cpu正在准备启动);}}});monitor.addLifecycleListener(new LifecycleListener() {Overridepublic void lifecycleEvent(LifecycleEvent event) {if (event.getType().equals(Lifecycle.AFTER_STOP_EVENT)) {System.out.println(已经监听到显示器 已经停止);}}});//启动computer.start();System.out.println(------------------------------------------);computer.stop();}} 运行结果 电脑 准备启动
电脑 正在启动
电脑在启动过程中 需要先启动子组件
CPU 准备启动
已经监听到 cpu正在准备启动
CPU 正在启动
CPU在启动过程中 负载达到了100%!
CPU 启动完毕
显示器 准备启动
显示器 正在启动
显示器在启动过程中 屏幕 很亮
显示器 启动完毕
电脑 启动完毕
------------------------------------------
电脑 准备关闭
电脑 正在关闭
电脑在关闭过程中 需要先关闭子组件
CPU 准备关闭
CPU 正在关闭
CPU在关闭过程中 负载下降到了1%!
CPU 关闭完毕
显示器 准备关闭
显示器 正在关闭
显示器在关闭过程中 屏幕渐渐暗了下去
显示器 关闭完毕
已经监听到显示器 已经停止
电脑 关闭完毕 从源码可以看到每个组件的启动都会调用父类的start()方法而start()方法又会调用本类的startInternal()方法stop方法类似。在父类的start()方法定义了一些组件共性的动作而在startInternal()方法中定义了组件自己的特殊动作。并且每个组件都可以自行添加自己的监听器。从运行的代码可以看到只要设置好每个组件的关系就可以统一管理每个组件的启动关闭了。Catalina中的生命周期管理的模式大概就是这样下面我们找个具体的类来分析。 我们主要分析start()方法相关其他类似init(),stop(),destroy()方法都是类似的。我们从前面的文章可以知道Tomcat启动的时候是调用了Bootstrap类的main()方法而main()方法中最后调用了Catalina类的start()方法我们查看Catalina类的start()方法其中 getServer().start(); 这一步又调用了StandardServer类的start()方法从这里就Catalina是最顶层组件下面所有的组件都开始需要进行生命周期管理了。所以查看StandardServer类的定义 public final class StandardServer extends LifecycleMBeanBase implements Server 再查看LifecycleMBeanBase类的定义 public abstract class LifecycleMBeanBase extends LifecycleBase implements MBeanRegistration 我们在这里就看到了上文介绍的关键类LifecycleBase类。之所以有个LifecycleMBeanBase类横跨在这里主要是因为Tomcat要将组件纳入JMX管理所以用这个类来实现这个不再本文的讲解范围之内所以暂时不讨论可以当作组件直接继承LifecycleBase类。 既然StandardServer类直接继承了LifecycleBase类那么Catalina调用StandardServer类的start()方法就是调用LifecycleBase类的start()方法(这样的前提是StandardServer,LifecycleMBeanBase类中没有start()方法实际上这2个类的确没有实现start()方法)。上篇文章已经分析过LifecycleBase类的start()方法具体源码因为start()方法中会调用子类的startInternal()方法所以可以直接查看StandardServer类的startInternal()方法。 Override
protected void startInternal() throws LifecycleException {fireLifecycleEvent(CONFIGURE_START_EVENT, null);setState(LifecycleState.STARTING);globalNamingResources.start();// Start our defined Servicessynchronized (servicesLock) {for (int i 0; i services.length; i) {services[i].start();}}
} 可以看到思路非常简单 触发某个事件(针对自己内部所有监听器)更改自己组件状态调用子组件的start()方法包括globalNamingResources和StandardService。至于这些子组件什么时候设置到本类中的读者可以自行发现。 我们可以继续往下再看一点既然调用了StandardService的start()方法查看StandardService类的定义。 public class StandardService extends LifecycleMBeanBase implements Service 类似StandardServer那么直接查看其startInternal()方法。 Override
protected void startInternal() throws LifecycleException {if(log.isInfoEnabled())log.info(sm.getString(standardService.start.name, this.name));setState(LifecycleState.STARTING);// Start our defined Container firstif (container ! null) {synchronized (container) {container.start();}}synchronized (executors) {for (Executor executor: executors) {executor.start();}}// Start our defined Connectors secondsynchronized (connectorsLock) {for (Connector connector: connectors) {try {// If it has already failed, dont try and start itif (connector.getState() ! LifecycleState.FAILED) {connector.start();}} catch (Exception e) {log.error(sm.getString(standardService.connector.startFailed,connector), e);}}}
} 虽然代码看起来很多但是按照上面的思路来看的话还是那几步。 更改当前组件状态调用自己子组件的start()方法包含container,connector看到这里我们就不继续往下看了因为之前启动的文章都已经分析过了是不是觉得看到这里对启动的流程理解又上了一层。其实自己看看每个组件的startInternal()方法都是在启动自己的子组件而组件的子组件可以从哪里找到呢可以看看Digster那篇文章疑惑看看server.xml也许会有恍然大悟的感觉至于具体代码去哪里找读者可以自行挖掘。 写到这里只能感慨Tomcat设计者设计的精巧代码的简洁简直完美 转载于:https://www.cnblogs.com/coldridgeValley/p/5816417.html