Spring bean生命週期詳解

上下文ApplicationContext容器中的生命週期:

bean: java

package com.pas.service;
//引包
public class PersonService implements BeanNameAware, BeanFactoryAware,
		ApplicationContextAware, InitializingBean, DisposableBean {

	private String name;

	public PersonService() {
		System.out.println("Person" + this.hashCode() + "實例化!");
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
		System.out.println("set方法被調用");
	}

	public void sayHi() {
		System.out.println("hi:" + this.name);
	}
        //自定義的初始化函數
	public void myinit() {
		System.out.println("myinit被調用");
	}

	@Override
	public void setBeanName(String name) {
		System.out.println("setBeanName被調用:" + name);
	}

	/*
	 * 傳遞bean工廠
	 */
	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		System.out.println("setBeanFactory被調用");
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		System.out.println("setApplicationContext被調用");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("afterPropertiesSet被調用");
	}
        //自定義的銷燬方法,配置見配置文件節
	public void mydes() throws Exception {
		System.out.println("mydes被調用,釋放各類資源");
	}

	@Override
	public void destroy() throws Exception {
		System.out.println("destroy被調用,釋放各類資源");
	}
}
測試函數:
package com.pas.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.pas.service.PersonService;

public class Test {
	public static void main(String[] args) {
		/*
		 * 上下文ApplicationContext中的生命週期:(此處爲單例scope)
		 * 一、實例化(默認使用無參數的構造函數)
		 * 	    能夠重載一個無參數的構造方法
		 *    若是須要使用有參的構造函數實例化,須要指定factory-method等參數
		 * 二、設置屬性(注入屬性)
		 * 		調用set方法設置屬性
		 * 三、若是實現bean名字關注BeanNameAware,調用BeanNameAware的setBeanName方法
		 * 四、若是實現bean工廠關注BeanFactoryAware,調用其setBeanFactory可獲得factory
		 * 五、若是你實現了 ApplicationContextAware接口,則調用方法 setApplicationContext
		 * 		該方法傳遞ApplicationContext
		 * 六、若是bean 和 一個後置處理器關聯,則會自動去調用 
		 * 		postProcessBeforeInitialization方法
		 * 		(面向全部對象編程,切面編程)
		 * 七、若是實現InitializingBean接口,則調用afterPropertiesSet
		 * 八、若是配置了自定義的初始化方法,(init-method="myinit")則執行其與7以後,postProcessAfterInitialization方法
		 * 九、若是bean 和 一個後置處理器關聯,
		 * 		則會自動去調用 postProcessAfterInitialization方法
		 * 十、使用咱們的bean
		 * 十一、容器關閉
		 * 十二、能夠經過實現DisposableBean 接口來調用方法 destory
		 * 1三、能夠在<bean destory-method="mydes"/> 調用定製的銷燬方法
		 * 
		 * 		實際開發中常見爲:1->2->6->10->9->11 
		 * 		實例化->set方法->後置處理器before->使用->後置處理器before->容器關閉
		 */
		ApplicationContext ac = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		
		out("xml加載完畢");
		try {
			PersonService ps=(PersonService) ac.getBean("personService2");
			ps.sayHi();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void out(Object s)
	{
		System.out.println(s);
	}
}

配置文件applicationContext.xml: spring

<!-- scope="prototype"爲原型模式,每次獲取都建立新對象 -->
	<bean id="personService" destroy-method="mydes" 
            init-method="myinit" class="com.pas.service.PersonService">
		<property name="name">
			<value>pingansheng</value>
		</property>
	</bean>
	<bean id="personService2" scope="prototype" 
                class="com.pas.service.PersonService">
		<property name="name">
			<value>小紅</value>
		</property>
	</bean>
	<!-- 配置自定義的後置處理器 -->
	<bean id="postProcessor" class="com.pas.service.MyBeanPostProcessor" />

後置處理器MyBeanPostProcessor: shell

package com.pas.service;
//import
public class MyBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println("以前作些事");
		System.out.println("postProcessBeforeInitialization被調用");
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println("以後作些事");
		System.out.println("postProcessAfterInitialization被調用");
		return bean;
	}

}
測試輸出:
bean工廠加載完畢
Person1640499969實例化!
set方法被調用
setBeanName被調用:personService
setBeanFactory被調用
afterPropertiesSet被調用
myinit被調用
hi:pingansheng
圖示:


Bean工廠容器bean的生命週期: 編程

大部分代碼相同,測試代碼稍有差異: app

package com.pas.test;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;

import com.pas.service.PersonService;

public class Test {
	public static void main(String[] args) {
		/*
		 * bean工廠中bean的生命週期:
		 * 一、實例化(默認使用無參數的構造函數)
		 * 	    能夠重載一個無參數的構造方法
		 *    若是須要使用有參的構造函數實例化,須要指定factory-method等參數
		 * 二、設置屬性(注入屬性)
		 * 		調用set方法設置屬性
		 * 三、若是實現bean名字關注BeanNameAware,調用BeanNameAware的setBeanName方法
		 * 四、若是實現bean工廠關注BeanFactoryAware,調用其setBeanFactory可獲得factory
		 * 五、若是實現InitializingBean接口,則調用afterPropertiesSet
		 * 六、若是配置了自定義的初始化方法,(init-method="myinit")則執行其與7以後,postProcessAfterInitialization方法
		 * 七、使用咱們的bean
		 * 八、容器關閉
		 * 九、能夠經過實現DisposableBean 接口來調用方法 destory
		 * 十、能夠在<bean destory-method="mydes"/> 調用定製的銷燬方法
		 */
		
		BeanFactory fc=new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
		out("bean工廠加載完畢");
		try {
			PersonService ps=(PersonService) fc.getBean("personService");
			ps.sayHi();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	public static void out(Object s)
	{
		System.out.println(s);
	}
}



控制檯輸出:
bean工廠加載完畢
Person371789756實例化!
set方法被調用
setBeanName被調用:personService
setBeanFactory被調用
afterPropertiesSet被調用
myinit被調用
hi:pingansheng



圖示:
相關文章
相關標籤/搜索