Bean的生命周期

1. 生命周期流程图

输入图片说明

2.Bean声明周期详细描述

  1. Spring 对Bean 进行实例化。
  2. Spring 将值和Bean 的引用注入进Bean 对应的属性中。
  3. 如果Bean 实现了BeanNameAware接口,Spring 将Bean的ID传递给setBeanName() 接口方法。
  4. 如果Bean 实现了BeanFactoryAware接口,Spring 将调用setBeanFactory()接口方法,将BeanFactory 容器实例传入。
  5. 如果Bean 实现了ApplicationContextAware 接口,Spring 将调用setApplicationContext()接口方法,将应用上下文的引用传入。
  6. 如果Bean 实现了BeanPostProcessor 接口,Spring 将调用它们的postProcessBeforeInitialization() 接口方法。
  7. 如果Bean 实现了InitializingBean 接口,Spring 将调用它们的afterPropertiesSet() 接口方法。类似地,如果Bean 使用init-method 声明了初始化方法,该方法也会被调用。
  8. 如果Bean 实现了BeanPostProcessor 接口,Spring 将调用它们的postPoressAfterInitialization() 接口方法。
  9. 此时此刻,Bean 已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁。
  10. 如果Bean 实现了DisposableBean 接口,Spring 将调用它的destroy()接口方法。同样,如果Bean 使用destroy-method 声明了销毁方法,该方法也会被调用。

3实例

首先是一个简单的Spring Bean,它实现了BeanNameAware,BeanFactoryAware,InitializingBean,ApplicationContextAware和DiposableBean这5个接口,同时有2个方法(myInit()方法和myDestroy方法),对应配置文件中<bean>的init-method和destroy-method。

package com.sjf.bean;
 
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
 
/**
 * Student实体类
 * @author sjf0115
 *
 */
public class Student implements BeanNameAware,BeanFactoryAware,InitializingBean,ApplicationContextAware, DisposableBean{
	
	private String name;
	private int age;
	private String school;
	
	// 构造器
	public Student(){
		System.out.println("constructor Student...");
	}
	
	public void setName(String name) {
		this.name = name;
		System.out.println("setName...");
	}
 
	public void setAge(int age) {
		this.age = age;
		System.out.println("setAge...");
	}
 
	public void setSchool(String school) {
		this.school = school;
		System.out.println("setSchool...");
	}
 
	public void myInit(){
		System.out.println("init-method...");
	}
	
	public void myDestroy(){
		System.out.println("destroy-method...");
	}
	
	// 来自于BeanNameAware接口
	public void setBeanName(String arg0) {
		System.out.println("setBeanName...[" + arg0 + "]");
	}
	
	// 来自于BeanFactoryAware接口
	public void setBeanFactory(BeanFactory arg0) throws BeansException {
		System.out.println("setBeanFactory...");
	}
	
	// 来自于InitializingBean
	public void afterPropertiesSet() throws Exception {
		System.out.println("afterPropertiesSet...");
	}
	
	// 来自于DisposableBean
	public void destroy() throws Exception {
		System.out.println("destroy...");
	}
	// 来自于ApplicationContextAware接口
	public void setApplicationContext(ApplicationContext arg0) throws BeansException {
		System.out.println("setApplicationContext...");
	}
	
	@Override
	public String toString() {
		return "name:" + name + "   age:" + age + "   school:" + school;
	}
}

然后是自定义一个MyBeanPostProcessor Bean,实现了BeanPostProcessor接口。

package com.sjf.bean;
 
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
 
/**
 * 自定义BeanPostProcessor
 * @author sjf0115
 *
 */
public class MyBeanPostProcessor implements BeanPostProcessor{
	
	public MyBeanPostProcessor(){
		System.out.println("constructor MyBeanPostProcessor...");
	}
	
	// 来自于BeanPostProcessor接口
	public Object postProcessAfterInitialization(Object arg0, String arg1) throws BeansException {
		System.out.println("postProcessAfterInitialization...[" + arg1 + "]");
		return arg0;
	}
		
	// 来自于BeanPostProcessor接口
	public Object postProcessBeforeInitialization(Object arg0, String arg1) throws BeansException {
		System.out.println("postProcessBeforeInitialization...[" + arg1 + "]");
		return arg0;
	}	
}

配置文件applicationContext.xml:

<?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 = "yoona" class = "com.sjf.bean.Student" scope="singleton" init-method="myInit" destroy-method="myDestroy">
		<property name="name" value="yoona"/>
		<property name="age" value="24"/>
		<property name="school" value="西电"/>
	</bean>
	
	<bean id = "myBeanPostProcessor" class="com.sjf.bean.MyBeanPostProcessor"/>
</beans>

测试代码:

package com.sjf.bean;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
 
/**
 * 测试类
 * @author sjf0115
 *
 */
public class Test {
 
	private static ApplicationContext context;
	private static Student stu;
	
	public static void main(String[] args) {
		context = new ClassPathXmlApplicationContext("applicationContext.xml");
		// 2. 从IOC容器中获取Bean实例
		stu = (Student)context.getBean("yoona");
		// 3.调用listAllBook方法
		System.out.println(stu.toString());
		// 4.关闭容器
		((ClassPathXmlApplicationContext) context).registerShutdownHook();
	}
}

运行结果:

constructor MyBeanPostProcessor...
constructor Student...
setName...
setAge...
setSchool...
setBeanName...[yoona]
setBeanFactory...
setApplicationContext...
postProcessBeforeInitialization...[yoona]
afterPropertiesSet...
init-method...
postProcessAfterInitialization...[yoona]
name:yoona   age:24   school:西电
destroy...
destroy-method...

结果分析

从这个运行结果中我们就可以看出一个Bean的生命周期:constructor(实例化) -> setXXX(填充属性) -> BeanName(BeanNameAware接口) -> BeanFactory(BeanFactoryAware接口) -> ApplicationContext(ApplicationContextAware接口) -> postProcessBeforeInitialization(BeanPostProcessor接口) -> afterPropertiesSet(InitializingBean接口) -> init-method(定制的初始化方法) -> postProcessAfterInitialization(BeanPostProcessor接口) -> destroy(DisposableBean接口) -> destroy-method(定制的销毁方法)

总结

  • 步骤1,2,是new一个bean,创建bean的构造函数,并对bean的属性和引用进行创建。
  • 步骤3,是设置bean的标识,提供回调自身的能力。
  • 步骤 4,5 ,是选择一直IOC容器初始化的方式,通过BeanFactor初始化或者ApplicationContext。
  • 步骤 6,7,8。是Bean初始化和初始化之前和之后的一些操作。 实现Initialization ,实现afterPropertiesSet方法。BeanPostProcessor 的接口包含了BeanInit之前和之后的方法。
  • 步骤9 ,是Bean时间示例好了,可以供应用程序使用了。
  • 步骤10,是Bean的销毁,实现 DisposableBean接口。
  • init-method 和 destroy-method 是用户自定义的初始化和销毁方法。

Aware相关接口

1.1、Spring提供一些Aware接口:

beanNameAware接口:如果某个bean需要访问配置文件中本身bean的id属性,这个Bean类通过实现该接口,在依赖关系确定之后,初始化方法之前,提供回调自身的能力,从而获得本身bean的id属性,该接口提供了void setBeanName(String name)方法实现,需要指出的是该方法的name参数就是该bean的id属性,加调该setBeanName方法可以让bean获取得自身的id属性

BeanFactoryAware接口:实现了BeanFactoryAware接口的bean,可以直接通过beanfactory来访问spring的容器,当该bean被容器创建以后,会有一个相应的beanfactory的实例引用,该 接口有一个方法void setBeanFactory(BeanFactory beanFactory)方法通过这个方法的参数创建它的BeanFactory实例,实现了BeanFactoryAware接口,就可以让Bean拥有访问Spring容器的能力。缺点:导致代码与spring的api耦合在一起,这种方式不推荐。

ApplicationContextAware接口:在Bean类被初始化后,将会被注入applicationContext实例,该接口有一个方法,setApplicationContext(ApplicationContext context),使用其参数context用来创建它的applicationContext实例,缺点:导致代码与spring的api耦合在一起,这种方式不推荐。

二、BeanPostProcessor类 和BeanFactoryPostProcessor

对容器中的Bean进行处理,实现BeanPostProcessor接口Bean后处理器

 // 第一个参数初始化的Bean第二个参数是Bean 实例的名称
public Object postProcessAfterInitialization(Object arg0, String arg1);在bean初始化之后的操作

public Object postProcessBeforeInitialization(Object arg0, String arg1);在bean初始化之前的操作

容器后处理器在容器实例化结束后,对容器进行额外的处理,必须实现BeanFactoryPostProcessor接口,

public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)

//Spring撮提供了很多后窗口处理器如:
//PropertyPlaceholderConfigurer:属性占位符配置器
//PropertyOverrideConfigurer:另外一种属性占位符配置器

2种的区别在与后面一种具有覆盖的性质

转载于:https://my.oschina.net/u/3421984/blog/1604747

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值