spring中Bean的生命周期
Posted Sup_Heaven
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring中Bean的生命周期相关的知识,希望对你有一定的参考价值。
Web容器Tomcat或Resin启动的时候会去加载web.xml。我们在web.xml中增加
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
或:
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
那么Web容器会默认自动加载/WEB-INF/applicationContext.xml初始化,一般通过
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
去寻找类路径(一般我们设置为WebRoot/WEB-INF/classes)下面的applicationContext.xml。
(1)Bean的建立:容器寻找Bean的定义信息并将其实例化。
(2)属性注入:使用依赖注入,Spring按照Bean定义信息配置Bean所有属性
(3)BeanNameAware的setBeanName():如果Bean类有实现org.springframework.beans.BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。
(4)BeanFactoryAware的setBeanFactory():如果Bean类有实现org.springframework.beans.factory.BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。
(5)BeanPostProcessors的ProcessBeforeInitialization():如果有org.springframework.beans.factory.config.BeanPostProcessors和Bean关联,那么其postProcessBeforeInitialization()方法将被将被调用。
(6)initializingBean的afterPropertiesSet():如果Bean类已实现org.springframework.beans.factory.InitializingBean接口,则执行他的afterProPertiesSet()方法。
(7)Bean定义文件中定义init-method:可以在Bean定义文件中使用"init-method"属性设定方法名称例如。如果有以上设置的话,则执行到这个阶段,就会执行initBean()方法。
(8)BeanPostProcessors的ProcessaAfterInitialization():如果有任何的BeanPostProcessors实例与Bean实例关联,则执行BeanPostProcessors实例的ProcessaAfterInitialization()方法。
此时,Bean已经可以被应用系统使用,并且将保留在BeanFactory中知道它不在被使用。有两种方法可以将其从BeanFactory中删除掉
(1)DisposableBean的destroy():在容器关闭时,如果Bean类有实现org.springframework.beans.factory.DisposableBean接口,则执行他的destroy()方法。
(2)Bean定义文件中定义destroy-method:在容器关闭时,可以在Bean定义文件中使用"destroy-method"属性设定方法名称。
如果有以上设定的话,则进行至这个阶段时,就会执行destroy()方法,如果是使用ApplicationContext来生成并管理Bean的话则稍有不同,使用ApplicationContext来生成及管理Bean实例的话,在执行BeanFactoryAware的setBeanFactory()阶段后,若Bean类上有实现org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,接着才执行BeanPostProcessors的ProcessBeforeInitialization()及之后的流程。
代码测试:
在applicationContext.xml中配置如下:
<bean id="teacher" class="com.lxq.test.Teacher" init-method="init"
destroy-method="destroy">
<constructor-arg type="java.lang.String" index="0">
<value>default_xml_constructor</value>
</constructor-arg>
<property name="name">
<value>default_xml_property</value>
</property>
</bean>
<bean id="myBeanPostProcessor" class="com.lxq.test.MyBeanPostProcessor" >
</bean>
Teacher类,继承一些接口:
package com.lxq.test;
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.InitializingBean;
public class Teacher implements BeanFactoryAware, BeanNameAware,
InitializingBean
private String name;
private Integer age;
private String beanName;
private BeanFactory beanFactory;
public void setName(String name)
System.out.println("这是在调用Teacher-setName,将名字由" + this.name + "设置为"
+ name);
this.name = name;
public Teacher(String name)
System.out.println("这是在调用Teacher的构造方法,将名字由" + this.name + "设置为" + name);
public void init()
this.name = "default_init";
System.out.println("这是Teacher-init,将名字由" + this.name
+ "设置为default_init");
public void destroy()
System.out.println("这是Teacher-destroy");
public void display()
System.out.println(this.name + "-" + this.age);
public void afterPropertiesSet() throws Exception
System.out.println("InitializingBean-afterPropertiesSet:name is "
+ name);
public void setBeanName(String name)
this.beanName=name;
System.out.println("BeanNameAware-setBeanName,beanName is " + name);
public void setBeanFactory(BeanFactory beanFactory) throws BeansException
this.beanFactory=beanFactory;
System.out.println("BeanFactoryAware-setBeanFactory,beanFactory is "
+ beanFactory);
package com.lxq.test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
*
* @author lxq
* 一旦MyBeanPostProcessor实现了接口BeanPostProcessor,并在xml中或利用annotation进行bean的注册,那么所有的bean都会执行下面的两个方法
*/
public class MyBeanPostProcessor implements BeanPostProcessor
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException
if (bean instanceof Teacher)
System.out
.println("BeanPostProcessor-postProcessAfterInitialization");
return bean;
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException
if (bean instanceof Teacher)
((Teacher) bean).setName("default_processor");
System.out
.println("BeanPostProcessor-postProcessBeforeInitialization,这是在init之前进行修改bean的属性值,把name修改为default_processor");
return bean;
BeanLifecycleManangeTest测试类:
package com.lxq.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanLifecycleManangeTest
public static void main(String[] args)
ApplicationContext ac = new ClassPathXmlApplicationContext(
new String[] "beans.xml" );
/** 调用getbean方法 */
Teacher t = (Teacher) ac.getBean("teacher");
t.display();
/** 调用close方法关闭bean */
AbstractApplicationContext aac = (AbstractApplicationContext) ac;
aac.close();
输出结果:
这是在调用Teacher的构造方法,将名字由null设置为default_xml_constructor
这是在调用Teacher-setName,将名字由null设置为default_xml_property
BeanNameAware-setBeanName,beanName is teacher
BeanFactoryAware-setBeanFactory,beanFactory is org.springframework.beans.factory.support.DefaultListableBeanFactory@39cf4a2c: defining beans [generatedOrderidServiceBean,其他的省略]; root of factory hierarchy
这是在调用Teacher-setName,将名字由default_xml_property设置为default_processor
BeanPostProcessor-postProcessBeforeInitialization,这是在init之前进行修改bean的属性值,把name修改为default_processor
InitializingBean-afterPropertiesSet:name is default_processor
这是Teacher-init,将名字由default_init设置为default_init
BeanPostProcessor-postProcessAfterInitialization
default_init-null
这是Teacher-destroy
源代码分析:
查看AbstractAutowireCapableBeanFactory的initializeBean,可以看到一个大概的执行过程,查看每个方法中更具体的可以发现基本就是上面所讲的bean的生命周期或者说只是创建过程。
invokeAwareMethods
applyBeanPostProcessorsBeforeInitialization
invokeInitMethods
applyBeanPostProcessorsAfterInitialization
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd)
if (System.getSecurityManager() != null)
AccessController.doPrivileged(new PrivilegedAction<Object>()
@Override
public Object run()
invokeAwareMethods(beanName, bean);
return null;
, getAccessControlContext());
else
invokeAwareMethods(beanName, bean);
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic())
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
try
invokeInitMethods(beanName, wrappedBean, mbd);
catch (Throwable ex)
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
if (mbd == null || !mbd.isSynthetic())
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
以上是关于spring中Bean的生命周期的主要内容,如果未能解决你的问题,请参考以下文章