[Spring]Bean在IOC容器的生命周期
[Spring]Bean在IOC容器的生命周期
·
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属性指定的销毁方法
更多推荐
已为社区贡献1条内容
所有评论(0)