自己动手写spring(五) bean的生命周期管理

前言

众所周知,使用Class的newInstance方法,就算是调用了bean的构造方法。bean是不能控制自己何年何月何日生(死)的,但bean可以和bean工厂约定一些规则(也就是实现特定的方法),决定下生死时刻要做些什么。

bean生命周期管理,主要涉及到标签中的init-method,destroy-method以及InitializingBean,DisposableBean接口。

InitializingBean

调用时机,当一个bean构造完成的时候调用。对前文和反射概念有一定了解的童鞋来说,实现起来不难。

public class BeanFactory {

public Object getBean(String beanId) throws Exception {
Object obj = beanId2Class.get(beanId);
if (obj != null) {
return obj;
}
obj = getBeanFromXml(beanId);
obj = getBeanFromAnnotation(beanId);
// 为了不给BeanFactory类增加负担,我们将这个逻辑提出来
InitializingBeanProcessor.process(obj, beanId2Bean.get(beanId),beanId2Clazz.get(beanId));
return obj;
}
}

public class InitializingBeanProcessor {
public static void process(Object obj, Bean bean,Class clazz) throws Exception {
Class[] intfs = clazz.getInterfaces();
for(Class intf : intfs){
if(intf.getSimpleName().equals("InitializingBean")){
Method m = clazz.getMethod("afterPropertiesSet", null);
m.invoke(obj, null);
break;
}
}
}
}

init-method




为bean标签类中添加init-method和destroy-method属性,并调用它们,也不是难事。

public class InitializingBeanProcessor {
public static void process(Object obj, Bean bean,Class clazz) throws Exception {
// 处理init-method标签
String initMethodName = bean.getInitMethodName();
if(StringUtils.isNotEmpty(initMethodName)){
Method m = clazz.getMethod(initMethodName, null);
m.invoke(obj, null);
}
// 处理InitializingBean的afterPropertiesSet方法
Class[] intfs = clazz.getInterfaces();
for(Class intf : intfs){
if(intf.getSimpleName().equals("InitializingBean")){
Method m = clazz.getMethod("afterPropertiesSet", null);
m.invoke(obj, null);
break;
}
}
}
}

DisposableBean和destroy-method

何时调用DisposableBean的方法和destroy-method,当然是系统运行结束退出的时候,但系统什么时候退出呢?这就用到了shutdownHook(这可是java基础喔,在spring之前就有喔)。

public class BeanFactory {
private Thread shutdownHook;
public BeanFactory() {
try {
loadXml();
loadAnnotation();
registerShutdownHook();
} catch (Exception e) {
e.printStackTrace();
}
}
public void registerShutdownHook() {
if (this.shutdownHook == null) {
// No shutdown hook registered yet.
this.shutdownHook = new Thread() {
@Override
public void run() {
destroyBeans();
}
};
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
}
}
protected void destroyBeans() {
try {
DisposableBeanProcessor.process(beanId2Class, beanId2Bean,beanId2Clazz);
} catch (Exception e) {
e.printStackTrace();
}
}
}

DisposableBeanProcessor与InitializingBeanProcessor的逻辑类似,此处不在赘述。

下文,我们将讨论工厂bean的实现。

posted @ 2015-11-08 17:12  骨汤鸡蛋面  阅读(242)  评论(0)    收藏  举报