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()即可,想要组件变换生命状态只需调用对应的方法即可;若对组件的生命周期状态感兴趣,则需要添加监听器,届时好得到状态变化的通知。还算比较简单。