您的位置:首页 > 编程语言 > Java开发

[Spring]Bean在IOC容器的生命周期

2016-10-21 16:39 471 查看
Spring中整个Bean的生命周期经过了各个方法的调用,如下:

Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法

Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法。

容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。

工厂后处理器接口方法:这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

首先介绍Bean级生命周期接口:BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean

我将这四个接口分为两类:

前两个接口负责在实例化Bean时,为Bean注入beanName(Bean在IOC容器的ID)与beanFactory属性

/**
* BeanFactoryAware接口,只声明了一个方法:用来获取BeanFactory
* BeanNameAware接口,只声明了一个方法:用来获取BeanName
*/


后两个接口负责为Bean进行实例化之前初始化和销毁时销毁。

/**
* InitializingBean:
* 在spring初始化bean的时候,如果该bean是实现了InitializingBean接口,
* 并且同时在配置文件中指定了init-method,
* 系统则是先调用InitializingBean的afterPropertiesSet方法,
* 然后在调用init-method中指定的方法。
* */

/**
* DisposableBean:
* 在spring初始化bean的时候,如果该bean是实现了DisposableBean接口,
* 并且同时在配置文件中指定了destroy-method,
* 系统则是先调用DisposableBean的destroy方法,
* 然后在调用destroy-method中指定的方法。
*/


下面介绍容器级生命周期接口:InstantiationAwareBeanPostProcessor 和 BeanPostProcessor

/**
* InstantiationAwareBeanPostProcessor 接口本质是
* BeanPostProcessor的子接口,
* 一般我们继承Spring为其提供的适配器类
* InstantiationAwareBeanPostProcessorAdapter来使用它,
*
* 此接口可以在Bean实例化前、Bean实例化后分别进行操作
* 也可以对Bean实例化之后进行属性操作
*/


/**
* BeanPostProcessor接口包括2个方法
* postProcessAfterInitialization和postProcessBeforeInitialization,
* 这两个方法的第一个参数都是要处理的Bean对象,第二个参数都是Bean的name。
* 返回值也都是要处理的Bean对象。
*
* 此接口的方法可以对Bean的属性进行更改
*/


下面代码演示Bean的生命周期

Person - JavaBean

public class Person implements BeanFactoryAware, BeanNameAware,
InitializingBean, DisposableBean{

/**
* BeanFactoryAware接口,只声明了一个方法:用来获取BeanFactory
* BeanNameAware接口,只声明了一个方法:用来获取BeanName
*/

/**
* InitializingBean:
* 在spring初始化bean的时候,如果该bean是实现了InitializingBean接口,
* 并且同时在配置文件中指定了init-method,
* 系统则是先调用InitializingBean的afterPropertiesSet方法,
* 然后在调用init-method中指定的方法。
* */

/**
* DisposableBean:
* 在spring初始化bean的时候,如果该bean是实现了DisposableBean接口,
* 并且同时在配置文件中指定了destroy-method,
* 系统则是先调用DisposableBean的destroy方法,
* 然后在调用destroy-method中指定的方法。
*/

private String name;
private BeanFactory beanFactory;
private String beanName;

public Person() {
System.out.println("【构造器】调用Person的构造器实例化");
}

public String getName() {
return name;
}

public void setName(String name) {
System.out.println("【注入属性】注入属性name,---name="+name);
this.name = name;
}

@Override
public String toString() {
return "Person [name=" + name + "]";
}

@Override
public void destroy() throws Exception {
System.out.println("【DiposibleBean接口】调用" +
"DiposibleBean.destory()");
}

@Override
public void afterPropertiesSet() throws Exception {
System.out.println("【InitializingBean接口】调用" +
"InitializingBean.afterPropertiesSet()");
}

@Override
public void setBeanName(String beanName) {
System.out.println("【BeanNameAware接口】调用" +
"BeanNameAware.setBeanName()---beanName="+beanName);
this.beanName = beanName;
}

@Override
public void setBeanFactory(BeanFactory arg0) throws BeansException {
System.out.println("【BeanFactoryAware接口】调用" +
"BeanFactoryAware.setBeanFactory()");
this.beanFactory = arg0;
}

// 通过<bean>的init-method属性指定的初始化方法
public void myInit() {
System.out.println("【init-method】调用" +
"<bean>的init-method属性指定的初始化方法");
}

// 通过<bean>的destroy-method属性指定的初始化方法
public void myDestory() {
System.out.println("【destroy-method】调用" +
"<bean>的destroy-method属性指定的初始化方法");
}

}


BeanFactoryPostProcessor接口的实现,可修改XML对Bean配置的元信息

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{

/**
* BeanFactoryPostProcessor可以对bean的定义(配置元数据)进行处理。
* 也就是说,Spring IoC容器允许BeanFactoryPostProcessor
* 在容器实际实例化任何其它的bean之前读取配置元数据,并有可能修改它。
* 如果你愿意,你可以配置多个BeanFactoryPostProcessor。
* 你还能通过设置'order'属性来控制BeanFactoryPostProcessor的执行次序。
* */

public MyBeanFactoryPostProcessor() {
super();
System.out.println("这是BeanFactoryPostProcessor实现类构造器!!");
}

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)
throws BeansException {
System.out.println("BeanFactoryPostProcessor调用postProcessBeanFactory方法");
BeanDefinition bd = arg0.getBeanDefinition("person1");
bd.getPropertyValues().addPropertyValue("name", "张三三");
}
}


InstantiationAwareBeanPostProcessorAdapter的实现

public class MyInstantiationAwareBeanPostProcessor
extends InstantiationAwareBeanPostProcessorAdapter {

/**
* InstantiationAwareBeanPostProcessor 接口本质是
* BeanPostProcessor的子接口,
* 一般我们继承Spring为其提供的适配器类
* InstantiationAwareBeanPostProcessorAdapter来使用它,
*
* 此接口可以在Bean实例化前、Bean实例化后分别进行操作
* 也可以对Bean实例化之后进行属性操作
*/

public MyInstantiationAwareBeanPostProcessor (){
super();
System.out.println(
"这是InstantiationAwareBeanPostProcessorAdapter" +
"实现类构造器!!");
}

// 接口方法、实例化Bean之前调用
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass,
String beanName) throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor" +
"调用postProcessBeforeInstantiation方法");
return null;
}

/**
* postProcessAfterInitialization重写了BeanPostProcessor的方法。
*/
// 接口方法、实例化Bean之后调用
@Override
public Object postProcessAfterInitialization(Object bean,
String beanName) throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor" +
"调用postProcessAfterInitialization方法");
return bean;
}

/**
* 第三个方法postProcessPropertyValues用来操作属性,返回值也应该是PropertyValues对象
*/
// 接口方法、设置某个属性时调用
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor" +
"调用postProcessPropertyValues方法");
System.out.println("beanName="+beanName);
return pvs;
}
}


BeanPostProcessor的实现

public class MyBeanPostProcessor implements BeanPostProcessor {

/**
* BeanPostProcessor接口包括2个方法
* postProcessAfterInitialization和postProcessBeforeInitialization,
* 这两个方法的第一个参数都是要处理的Bean对象,第二个参数都是Bean的name。
* 返回值也都是要处理的Bean对象。
*
* 此接口的方法可以对Bean的属性进行更改
*/

public MyBeanPostProcessor() {
super();
System.out.println("这是BeanPostProcessor实现类构造器!!");
}

@Override
public Object postProcessAfterInitialization(Object obj, String objName)
throws BeansException {
Person person = (Person) obj;
person.setName("之后--赵六");
System.out.println("BeanPostProcessor接口方法" +
"postProcessAfterInitialization对属性进行更改!" +
"---"+"obj="+obj+"---objName="+objName);
return obj;
}

@Override
public Object postProcessBeforeInitialization(Object obj, String objName)
throws BeansException {
Person person = (Person) obj;
person.setName("之前--李四");
System.out.println("BeanPostProcessor接口方法" +
"postProcessBeforeInitialization对属性进行更改!" +
"---"+"obj="+obj+"---objName="+objName);
return obj;
}
}


XML配置信息

<bean id="beanPostProcessor"
class="com.bean.MyBeanPostProcessor">
</bean>

<bean id="instantiationAwareBeanPostProcessor"
class="com.bean.MyInstantiationAwareBeanPostProcessor">
</bean>

<bean id="beanFactoryPostProcessor"
class="com.bean.MyBeanFactoryPostProcessor">
</bean>

<bean id="person1" class="com.bean.Person" init-method="myInit"
destroy-method="myDestory" scope="singleton">
<property name="name" value="aaa"></property>
</bean>


测试代码

public static void main(String[] args) {
System.out.println("现在开始初始化IOC容器");
ApplicationContext context =
new ClassPathXmlApplicationContext("spring2.xml");
System.out.println("IOC容器初始化成功");
Person person = (Person) context.getBean("person1");
System.out.println("使用person对象的toString:"+person);
System.out.println("现在开始关闭容器!");
((ClassPathXmlApplicationContext)context).registerShutdownHook();
}


运行结果

现在开始初始化IOC容器
这是BeanFactoryPostProcessor实现类构造器!!
BeanFactoryPostProcessor调用postProcessBeanFactory方法
这是BeanPostProcessor实现类构造器!!
这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!
InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法
【构造器】调用Person的构造器实例化
InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法
beanName=person1
【注入属性】注入属性name,---name=张三三
【BeanNameAware接口】调用BeanNameAware.setBeanName()---beanName=person1
【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()
【注入属性】注入属性name,---name=之前--李四
BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!---obj=Person [name=之前--李四]---objName=person1
【InitializingBean接口】调用InitializingBean.afterPropertiesSet()
【init-method】调用<bean>的init-method属性指定的初始化方法
【注入属性】注入属性name,---name=之后--赵六
BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!---obj=Person [name=之后--赵六]---objName=person1
InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法
IOC容器初始化成功
使用person对象的toString:Person [name=之后--赵六]
现在开始关闭容器!
【DiposibleBean接口】调用DiposibleBean.destory()
【destroy-method】调用<bean>的destroy-method属性指定的初始化方法


总结:

整个Bean的生命周期
1、实例化BeanFactoryPostProcessor实现类
2、执行BeanFactoryPostProcessor的postProcessBeanFactory修改XML对Bean配置的元信息
3、实例化BeanPostProcessor实现类
4、实例化InstantiationAwareBeanPostProcessorAdapter实现类
5、InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法,Bean实例化之前调用此方法

new Bean(),开始进行注入属性

6、InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法,可以修改Bean的属性信息
7、读取第二步BeanFactoryPostProcessor的postProcessBeanFactory方法中修改的XML对Bean的配置的元信息,修改Bean的属性
8、调用BeanNameAware的setBeanName方法,为Bean注入beanName(Bean的ID)
9、调用BeanFactoryAware的setBeanFactory,为Bean注入BeanFactory
10、BeanPostProcessor实现类调用接口方法postProcessBeforeInitialization对属性进行更改
11、InitializingBean实现类调用afterPropertiesSet()进行Bean的初始化方法
12、调用<bean>的init-method属性指定的初始化方法
13、BeanPostProcessor实现类接口方法postProcessAfterInitialization对属性进行更改

Bean的属性注入完毕

14、InstantiationAwareBeanPostProcessor实现类调用postProcessAfterInitialization方法,Bean实例化之后调用此方法
15、IOC容器初始化成功,可以调用容器的Bean使用了

下面是销毁动作

16、调用DiposibleBean接口的destory方法
17、调用<bean>的destroy-method属性指定的销毁方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: