自己动手写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 id="beanA" name="test" class="org.lqk.lspring2.bean.BeanA" init-method="init" destroy-method="close">
	<property name="beanB" ref="beanB" />
	<property name="title" value="studentA" />
</bean>

为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  骨汤鸡蛋面  阅读(226)  评论(0编辑  收藏  举报