Java实现组件的生命周期
假如你在写平台或者一个比较大的项目,总会设计到多个模块,模块有大有小,往往模块之前是嵌入式(embbed)的,即小模块由大模块来管理,外层模块控制着里层模块。这时我们为这些组件设计一套通用的生命周期机制会是一种很好的实现方法,既加强了代码的组织也降低了维护的代价。
首先要实现一套生命周期机制需要哪些类呢?
- LifeCycle:代表生命周期
- LifeCycleState:代表生命周期状态
- LifeCycleEvent、LifeCycleListener:当状态改变时需要告诉监听者(监听器模式)
- LifeCycleException: 异常
定义一个接口表示生命周期(根据需求定义生命周期的阶段,这里简单实现):
package script.container.lifecycle; /** * 简单生命周期定义 * @author lixiaohui * */ public interface LifeCycle { void init() throws LifeCycleException; void start() throws LifeCycleException; void restart() throws LifeCycleException; void destroy() throws LifeCycleException; }
其抽象实现如下:
package script.container.lifecycle; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; /** * <pre> * {@link LifeCycle} 的抽象实现 * * 这里用了模板方法模式, 生命周期组件的总体流程由该类实现, 而具体的每个阶段干什么由具体的组件去实现. * </pre> * @author lixiaohui * */ public abstract class AbstractLifeCycle implements LifeCycle { private List<LifeCycleListener> lifeCycleListeners = new ArrayList<>(); /** * 这里需要保证state的可见性, 防止多个线程并发时出问题 */ protected volatile LifeCycleState state = LifeCycleState.NULL; public AbstractLifeCycle(){ addLifeCycleListener(new LifeCycleLogger()); } @Override public void init() throws LifeCycleException { if (state.compare(LifeCycleState.NULL) != 0) {// 不是初始前状态 return; } setState(LifeCycleState.INITIALIZING); try { initInternal(); } catch (LifeCycleException e) { setState(LifeCycleState.FAILED); throw e; } setState(LifeCycleState.INITIALIZED); } private void setState(LifeCycleState state, boolean fireEvent) { this.state = state; if(fireEvent){ fireLifeCycleEvent(new LifeCycleEvent(this, this, state)); } } private void setState(LifeCycleState state) { setState(state, true); } protected abstract void initInternal() throws LifeCycleException; @Override public void start() throws LifeCycleException { if(state.compare(LifeCycleState.INITIALIZED) != 0){ //不是已初始化 init(); } if(state.compare(LifeCycleState.INITIALIZED) != 0){ return; } setState(LifeCycleState.STARTING); try { startInternal(); } catch (LifeCycleException e) { setState(LifeCycleState.FAILED); throw e; } setState(LifeCycleState.STARTED); } protected abstract void startInternal() throws LifeCycleException; @Override public void restart() throws LifeCycleException { if(state != LifeCycleState.STARTED){ throw new LifeCycleException("Illegal lifecycle state: " + state); } setState(LifeCycleState.RESTARTING); try{ restartInternal(); } catch (LifeCycleException e){ setState(LifeCycleState.FAILED); } setState(LifeCycleState.RESTARTED); setState(LifeCycleState.STARTED, false); } protected abstract void restartInternal() throws LifeCycleException; @Override public void destroy() throws LifeCycleException { if(state.compare(LifeCycleState.STARTED) != 0){ //不是已初始化 return; } setState(LifeCycleState.DESTROYING); try { startInternal(); } catch (LifeCycleException e) { setState(LifeCycleState.FAILED); throw e; } setState(LifeCycleState.DESTROYED); } protected abstract void destroyInternal() throws LifeCycleException; protected abstract String name(); protected abstract String type(); private void fireLifeCycleEvent(LifeCycleEvent e) { fireLifeCycleEvent(e, false); } private void fireLifeCycleEvent0(LifeCycleEvent e) { for (LifeCycleListener l : lifeCycleListeners) { l.lifeCycleEvent(e); } } protected void fireLifeCycleEvent(LifeCycleEvent e, boolean asyc) { if (!asyc) { fireLifeCycleEvent0(e); } else { // 异步通知 new Thread(new Runnable(){ @Override public void run() { fireLifeCycleEvent0(e); } }).start(); } } public void addLifeCycleListener(LifeCycleListener l){ lifeCycleListeners.add(l); } public void removeLifeCycleListener(LifeCycleListener l){ lifeCycleListeners.remove(l); } // 日志打印, 可忽略 public class LifeCycleLogger implements LifeCycleListener { private final Logger logger = Logger.getLogger(LifeCycleLogger.class); @Override public void lifeCycleEvent(LifeCycleEvent e) { switch (e.getState()) { case INITIALIZING: logger.info(type() + " " + name() + " initializing..."); break; case INITIALIZED: logger.info(type() + " " + name() + " initialized..."); break; case STARTING: logger.info(type() + " " + name() + " starting..."); break; case STARTED: logger.info(type() + " " + name() + " started..."); break; case RESTARTING: logger.info(type() + " " + name() + " restarting..."); break; case RESTARTED: logger.info(type() + " " + name() + " restarted..."); break; case DESTROYING: logger.info(type() + " " + name() + " destorying..."); break; case DESTROYED: logger.info(type() + " " + name() + " destoryed..."); break; case FAILED: logger.info(type() + " " + name() + " failed..."); break; default: break; } } } }
监听器很简单:
package script.container.lifecycle; import java.util.EventListener; public interface LifeCycleListener extends EventListener { void lifeCycleEvent(LifeCycleEvent e); }
package script.container.lifecycle; import java.util.EventObject; public class LifeCycleEvent extends EventObject { private static final long serialVersionUID = 6757600267753576331L; private AbstractLifeCycle lifeCycle; private LifeCycleState state; public LifeCycleEvent(Object source, AbstractLifeCycle lifeCycle, LifeCycleState state) { super(source); this.lifeCycle = lifeCycle; this.state = state; } public AbstractLifeCycle getLifeCycle() { return lifeCycle; } public void setLifeCycle(AbstractLifeCycle lifeCycle) { this.lifeCycle = lifeCycle; } public LifeCycleState getState() { return state; } public void setState(LifeCycleState state) { this.state = state; } }
package script.container.lifecycle; /** * 生命周期State * @author lixiaohui * */ public enum LifeCycleState{ NULL(0),//初始前 INITIALIZING(1), INITIALIZED(2), STARTING(3), STARTED(4), RESTARTING(5), RESTARTED(6), DESTROYING(7), DESTROYED(8), FAILED(9); private int age; private LifeCycleState(int age){ this.age = age; } public int getAge() { return age; } public int compare(LifeCycleState s){ return age > s.getAge() ? 1 : (age == s.getAge() ? 0 : -1); } }
怎么用呢?组件只需继承AbstractLifeCycle并选择性实现initInternal()、startInternal()、restartInternal()和destroyInternal()即可,想要组件变换生命状态只需调用对应的方法即可;若对组件的生命周期状态感兴趣,则需要添加监听器,届时好得到状态变化的通知。还算比较简单。
相关推荐
用生命周期规范组件化流程 目录 * * * 写在前面 。demo 怎么做:一条commit对应一条规范。所以不会很快,可以先 star 收藏以便查阅。 本文是在我重构的时候,边组件化边记录下来的。期中踩了很多坑,也不断思考优雅...
基于AAC实现组件生命周期观察实践控件实现LifecycleObserver接口,内部通过@OnLifecycleEvent注解声明生命周期事件public class LifecycleObserverDemo implements LifecycleObserver { @OnLifecycleEvent(Lifecycle...
8.1 Java对象在JVM中的生命周期 8.2 理解Session的缓存 8.2.1 Session的缓存的作用 8.2.2 脏检查及清理缓存的机制 8.3 Java对象在Hibernate持久化层的状态 8.3.1 临时对象的特征 8.3.2 持久化对象的...
掌握在 Applet 容器中添加组件的方法,掌握使用布局管理器对组件进行管理的方法。 2. 理解 Java 的事件处理机制,掌握为不同组件编写事件处理程序的方法。...8. 了解 Applet 的生命周期。 9. 向applet中传递参数。
在小应用程序的生命周期中,只执行一次该方法,因此可以在其中进行一些只执 行一次的初始化操作,如处理由浏览器传递进来的参数、添加用户接口组件、加载图像和声 音文件等。 小应用程序有默认的构造方法,但它习惯...
搭建任意组件,设计多个界面,运行程序观察其生命周期的情况。 2. 使用Intent实现页面之间数据的传递。 3. 实验代码 AlifecyfleActivity.java package com.wr; import android.app.Activity; import android....
提供覆盖编译构建到代码运行的每个生命周期的插件体系,支持各种功能扩展和业务需求。同时支持配置式路由和约定式路由,保证路由的功能完备。整体上以约定、配置化、组件化的设计思想,让用户仅仅关心用组件搭建页面...
Spring框架为开发提供了一系列的解决方案,比如利用控制反转的核心特性,并通过依赖注入实现控制反转来实现管理对象生命周期容器化,利用面向切面编程进行声明式的事务管理,整合多种持久化技术管理数据访问,提供...
《JavaServer Faces 2.0完全参考手册》对所有jsf功能都进行了解释,包括请求处理生命周期、托管bean、页面导航、组件开发、ajax、验证器、国际化和安全。贯穿全书的专家组意见提供了关于jsf设计的内部信息。 推荐...
8.1 Java对象在JVM中的生命周期 8.2 理解Session的缓存 8.2.1 Session的缓存的作用 8.2.2 脏检查及清理缓存的机制 8.3 Java对象在Hibernate持久化层的状态 8.3.1 临时对象的特征 8.3.2 持久化对象的...
8.1 Java对象在JVM中的生命周期 8.2 理解Session的缓存 8.2.1 Session的缓存的作用 8.2.2 脏检查及清理缓存的机制 8.3 Java对象在Hibernate持久化层的状态 8.3.1 临时对象的特征 8.3.2 持久化对象的...
5.3 Applet的组成和生命周期 5.4 一个Applet例子 5.5 运行Java Applets 5.6 通用AWT组件 5.6.1 按钮 5.6.2 单选按钮(Radio Button) 5.6.3 作出重要选择 5.6.4 循环播放声音文件 5.6.5 文本域 5.6.6 标签 5.7 布局...
JIMU(积木)是一套Android组件化框架,支持组件的代码资源隔离,单独调试,集成调试,组件交互,UI转换,生命周期等完整功能。 取名为JIMU(积木),其含义是应用这套框架可以做到组件之间的完全隔离,每个组件可以...
JSF具有良好定义的请求处理生命周期和丰富的组件层次结构,旨在推动基于Java的Web用户界面开发的简易性。利用JSF提供的可重用、可扩展、基于组件的用户界面框架,在快速开发工具RAD的支持下,可以通过拖放组件的方式...
8.1 Java对象在JVM中的生命周期 8.2 理解Session的缓存 8.2.1 Session的缓存的作用 8.2.2 脏检查及清理缓存的机制 8.3 Java对象在Hibernate持久化层的状态 8.3.1 临时对象的特征 8.3.2 持久化对象的...
微信、阿里小程序渐进框架,全局存储状态管理、跨页面通讯、生命周期事件系统、组件props监听。支持微信小程序、支付宝小程序、淘宝小程序、钉钉小程序、高德小程序等
《JavaServer Faces 2.0完全参考手册》对所有jsf功能都进行了解释,包括请求处理生命周期、托管bean、页面导航、组件开发、ajax、验证器、国际化和安全。贯穿全书的专家组意见提供了关于jsf设计的内部信息。 推荐...
8.6.2 有状态Session Bean的生命周期 322 8.6.3 定制Session Bean的生命 周期行为 323 8.7 在Session Bean中使用事务 327 8.7.1 容器管理事务 327 8.7.2 Bean管理事务 330 8.8 拦截器 332 8.9 依赖注入 335 8.9.1 ...
9.6.1 Java国际化的思路 346 9.6.2 Java支持的语言和国家 346 9.6.3 完成程序国际化 347 9.6.4 使用MessageFormat处理包含占位符的字符串 349 9.6.5 使用类文件代替资源文件 350 9.6.6 使用NumberFormat格式化...