Spring框架(四)—— SpringBean 的生命週期

一、SpringBean 的生命週期

1、SpringBean 生命週期概述

Spring的生命週期是指實例化Bean時所經歷的一系列階段,即通過getBean()獲取bean對象及設置對象屬性時,Spring框架做了哪些事。Bean的生命週期從Spring容器實例化Bean到銷燬Bean。
當我們使用註解或者bean標籤,將對象的創建工作交給spring處理以後,該對象的生命週期就由spring容器來管理。

2、SpringBean 生命週期過程

Semon吹吹_Spring Bean生命週期
(1)實例化 Bean 對象

  • 調用實例化 Bean 對象之前的 InstantiationAwareBeanPostProcessorAdapter 接口的 postProcessBeforeInstantiation 方法
  • Bean 的創建,由 BeanFactory 讀取 Bean 定義文件,並生成各個實例
  • 調用實例化Bean對象之後的 InstantiationAwareBeanPostProcessorAdapter 接口的 postProcessAfterInstantiation 方法

(2)設置 Bean 對象屬性

  • 執行在 Bean 設置屬性時的 InstantiationAwareBeanPostProcessorAdapter 接口的 postProcessPropertyValues 方法,設置pvs值
  • Setter 注入,執行 Bean 的屬性依賴注入

(3)將容器和 bean 本身的信息暴露出來便於使用過程

  • 實現 BeanNameAware 接口,重寫並執行 setBeanName()。
  • 實現 BeanFactoryAware接口,重寫並執行 setBeanFactory()。

(4)初始化 Bean 對象過程

  • 調用初始化 Bean 對象之前的InstantiationAwareBeanPostProcessorAdapter 接口的 postProcessBeforeInitialization 方法
  • 繼承 InitializingBean 類,重寫 afterPropertiesSet(),完成初始化。
  • 在 xml 文件中的 Bean 標籤中使用 init-method 可以設置自定義初始化方法。
  • 調用初始化 Bean 對象之後的 InstantiationAwareBeanPostProcessorAdapter 接口的 postProcessAfterInitialization 方法。

(5)銷燬 Bean 對象過程

  • 實現 DisposableBean 接口,重寫 destroy(),在容器關閉時,如果 Bean 類實現了該接口,則執行它的 destroy() 方法
  • 在 xml 文件中的 Bean 標籤中定義 destroy-method,在容器關閉時,可以在 xml 文件中的 Bean 標籤中使用“destory-method”設置自定義的對象銷燬方法的方法

3、生命週期示例

(1)Student 實體類
分別實現 BeanNameAware 接口、BeanFactoryAware 接口、InitializingBean 接口、DisposableBean 接口

public class Student implements BeanNameAware,BeanFactoryAware,InitializingBean,DisposableBean{
	private String name;
	private int age;
	
	//無參構造
	public Student() {
		System.out.println("- 執行了無參構造");
	}
	//有參構造
	public Student(String name, int age) {
		System.out.println("- 執行了有參構造name=" + name + " age=" + age);
		this.name = name;
		this.age = age;
	}
	//get、set方法
	public String getName() {
		System.out.println("- 執行了getName()方法");
		return name;
	}
	public void setName(String name) {
		System.out.println("- 執行了setName()方法,調用了setter方法通過有參構造完成了屬性注入,name=" + name);
		this.name = name;
	}
	public int getAge() {
		System.out.println("- 執行了getAge()方法");
		return age;
	}
	public void setAge(int age) {
		System.out.println("- 執行了setAge()方法,調用了setter方法通過有參構造完成了屬性注入,age=" + age);
		this.age = age;
	}
	//已定義show()方法
	public void show() {
		System.out.println("- 執行了自定義的show()方法,name=" + name);
	}
	//自定義初始化對象方法init()
	public void init() {
		System.out.println("- 執行了自定義的初始化對象方法init()");
	}
	//自定義銷燬對象方法des()
	public void des() {
		System.out.println("- 執行了自定義的銷燬對象方法des()");
	}
	//實現BeanNameAware接口,重寫setBeanName()方法
	@Override
	public void setBeanName(String beanName) {
		System.out.println("- 執行了BeanNameAware接口的setBeanName()方法,將bean的id暴露出來,當前對象在容器中的beanid=" + beanName);
	}
	//實現BeanFactoryAware接口,重寫setBeanFactory()方法
	@Override
	public void setBeanFactory(BeanFactory factory) throws BeansException {
		System.out.println("- 執行了BeanFactoryAware接口的setBeanFactory()方法,將工廠對象暴露出來,通過該工廠可以獲取容器中的對象");
		System.out.print("this==factory.getBean(“student”)的值=");
		System.out.println(this==factory.getBean("student"));
	}
	//實現InitializingBean接口,重寫afterPropertiesSet()方法
	@Override
	public void afterPropertiesSet() throws Exception {
		 System.out.println("- 執行了InitializingBean接口的afterPropertiesSet()方法,初始化完成,完成了屬性的注入,name = " + name);
	}
	//實現DisposableBean接口,重寫destroy()方法
	@Override
	public void destroy() throws Exception {
		System.out.println("- 執行了DisposableBean接口的destroy()方法,容器被關閉,對象即將被銷燬,執行Spring自帶的銷燬方法");
	}
}

(2)繼承InstantiationAwareBeanPostProcessorAdapter類的Processor 類

//實例化之前、之後,初始化之前、之後,及框架設置Bean屬性時調用該接口
public class Processor extends InstantiationAwareBeanPostProcessorAdapter{
	//實例化之前
	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		System.out.println("- 執行了實例化Bean對象之前的InstantiationAwareBeanPostProcessorAdapter接口的postProcessBeforeInstantiation方法");
		return null;
	}
	//實例化之後
	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		System.out.println("- 執行了實例化Bean對象之後的InstantiationAwareBeanPostProcessorAdapter接口的postProcessAfterInstantiation方法");
		return true;
	}
	//Bean設置屬性
	@Override
	public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
		System.out.println("- 執行了在Bean設置屬性時的InstantiationAwareBeanPostProcessorAdapter接口的postProcessPropertyValues方法,設置pvs值=" + pvs);
		return pvs;
	}
	//初始化之前
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		Student student = (Student) bean;
		System.out.println("- 執行了初始化Bean對象之前的InstantiationAwareBeanPostProcessorAdapter接口的postProcessBeforeInitialization方法");
		student.setName("李四");
		return bean;
	}
	//初始化之後
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		Student student = (Student) bean;
		System.out.println("- 執行了初始化Bean對象之後的InstantiationAwareBeanPostProcessorAdapter接口的postProcessAfterInitialization方法");
		student.setAge(10);
		return bean;
	}
}

(3)xml 文件

<beans>
	<bean id="student" class="com.spring.demo3.entity.Student" init-method="init" destroy-method="des">
		<property name="name" value="張三"></property>
		<property name="age" value="20"></property>
	</bean>
	<bean class="com.spring.demo3.action.Processor"></bean>
</beans>

(5)Action 類

public class UserAction{
	public static void main(String[] args) {
		ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("spring3.xml");
		Student student = (Student) ac.getBean("student");
		student.show();
		ac.close();
	}
}

(6)得到結果

- 執行了實例化Bean對象之前的InstantiationAwareBeanPostProcessorAdapter接口的postProcessBeforeInstantiation方法
- 執行了無參構造
- 執行了實例化Bean對象之後的InstantiationAwareBeanPostProcessorAdapter接口的postProcessAfterInstantiation方法
- 執行了在Bean設置屬性時的InstantiationAwareBeanPostProcessorAdapter接口的postProcessPropertyValues方法,設置pvs值=PropertyValues: length=2; bean property 'name'; bean property 'age'
- 執行了setName()方法,調用了setter方法通過有參構造完成了屬性注入,name=張三
- 執行了setAge()方法,調用了setter方法通過有參構造完成了屬性注入,age=20
- 執行了BeanNameAware接口的setBeanName()方法,將bean的id暴露出來,當前對象在容器中的beanid=student
- 執行了BeanFactoryAware接口的setBeanFactory()方法,將工廠對象暴露出來,通過該工廠可以獲取容器中的對象
this==factory.getBean(“student”)的值=true
- 執行了初始化Bean對象之前的InstantiationAwareBeanPostProcessorAdapter接口的postProcessBeforeInitialization方法
- 執行了setName()方法,調用了setter方法通過有參構造完成了屬性注入,name=李四
- 執行了InitializingBean接口的afterPropertiesSet()方法,初始化完成,完成了屬性的注入,name = 李四
- 執行了自定義的初始化對象方法init()
- 執行了初始化Bean對象之後的InstantiationAwareBeanPostProcessorAdapter接口的postProcessAfterInitialization方法
- 執行了setAge()方法,調用了setter方法通過有參構造完成了屬性注入,age=10
- 執行了自定義的show()方法,name=李四
- 執行了DisposableBean接口的destroy()方法,容器被關閉,對象即將被銷燬,執行Spring自帶的銷燬方法
- 執行了自定義的銷燬對象方法des()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章