1. 程式人生 > >Spring容器中Bean的生命週期(init-method destroy-method)

Spring容器中Bean的生命週期(init-method destroy-method)

Spring容器中Bean的生命週期

這一篇很詳細的講了Bean生命週期的每一個過程。

    我主要是想實現一下init方法核destory方法,因為這個和AOP程式設計的環繞通知有點兒相似的感覺,所以特別來研究一下這兩個方法。

     在Spring配置中,init-method 用於配置初始化方法,準備資料等,destroy-method 用於配置銷燬方法,清理資源等。寫法為:

<bean id=""class="" init-method="初始化方法名稱"  destroy-method="銷燬的方法名稱">

    下面編寫程式碼來實現一下:

第一種方法,直接編寫init-method和destroy-method:

    編寫UserService介面,編寫介面的實現類(在實現類裡編寫init方法核destroy方法),配置xml,編寫測試類。【注意,這裡需要加上close方法,不然destory方法的輸出不會顯示。】

/**
 * 
 */
package com.Lily.SpringLearning.c_lifeCycle1;

/** 
 * * 
 * @author   LilyLee
 * @date     2017年6月14日
 * @time     上午9:10:25
 * @Version  1.0
 * @email    [email protected]
 *
 */
public interface UserService {
	public void addUser();
}

/**
 * 
 */
package com.Lily.SpringLearning.c_lifeCycle1;

/** 
 * * 
 * @author   LilyLee
 * @date     2017年6月14日
 * @time     上午9:11:13
 * @Version  1.0
 * @email    [email protected]
 *
 */
public class UserServiceImpl implements UserService {

	
	@Override
	public void addUser() {
		// TODO Auto-generated method stub
	System.out.println("addUser()");
	}
	
	public void myInit(){
		System.out.println("init()");
	}
	
	public void myDestory(){
		System.out.println("destory()!");
	}
	

}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       					   http://www.springframework.org/schema/beans/spring-beans.xsd">

	
	<bean id="userServiceId" class="com.Lily.SpringLearning.c_lifeCycle1.UserServiceImpl" init-method="myInit" destroy-method="myDestory"></bean>
	
</beans>

/**
 * 
 */
package com.Lily.SpringLearning.c_lifeCycle1;

import static org.junit.Assert.*;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/** 
 * * 
 * @author   LilyLee
 * @date     2017年6月14日
 * @time     上午10:21:24
 * @Version  1.0
 * @email    [email protected]
 *
 */
public class Test {

	@org.junit.Test
	public void test() {
		String xmlPath ="com/Lily/SpringLearning/c_lifeCycle1/beans.xml";
		ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext(xmlPath);
		UserService u=(UserService) ac.getBean("userServiceId");
		u.addUser();
		ac.close();
	}

}


第二種方法,實現BeanPostProcessor介面。

    spring提供一種機制,只要實現此介面BeanPostProcessor,並將實現類提供給spring容器,spring容器將自動執行,在初始化方法前執行before(),在初始化方法後執行after()。

    spring提供工廠勾子(Factory hook),用於修改例項物件,可以生成代理物件,是AOP底層。

    與第一種方法的不同是,

    (1)增加了一個實現BeanPostProcessor介面的MyBeanPostProcessor類。這裡的後方法的return 需要用生成jdk代理的方式實現:

return Proxy.newProxyInstance(loader, interfaces, h)

    (2)配置xml的時候不需要再寫init那句了,後面只有一句:<bean class=”……”>

/**
 * 
 */
package com.Lily.SpringLearning.c_lifecycle2;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/** 
 * * 
 * @author   LilyLee
 * @date     2017年6月14日
 * @time     上午10:34:29
 * @Version  1.0
 * @email    [email protected]
 *
 */
public class MyBeanPostProcessor implements BeanPostProcessor{

	/* (non-Javadoc)
	 * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
	 */
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("前方法: "+beanName);
		return bean;
	}

	/* (non-Javadoc)
	 * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
	 */
	@Override
	public Object postProcessBeforeInitialization(final Object bean, String beanName)
			throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("後方法:  "+beanName);
		return Proxy.newProxyInstance(MyBeanPostProcessor.class.getClassLoader(),
				bean.getClass().getInterfaces(),
				new InvocationHandler() {
			
					
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						// TODO Auto-generated method stub
						System.out.println("----start");
						//執行目標方法
						Object o=method.invoke(bean, args);
						System.out.println("----submint");
						return o;
					}
				});

		
	}

}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       					   http://www.springframework.org/schema/beans/spring-beans.xsd">

	
	<bean id="userServiceId" class="com.Lily.SpringLearning.c_lifecycle2.UserServiceImpl" ></bean>
	<bean class="com.Lily.SpringLearning.c_lifecycle2.MyBeanPostProcessor"></bean>
	
	
</beans>