bean的生命周期
Bean is ready for use:
1.container找到bean类的定义并实例化该bean
2.使用DI,设置属性。(调用setXXX)
3.如果Bean实现了BeanNameAware,factory 将bean的id传入setBeanName()
4.如果Bean实现了BeanFactoryAware,factory 讲自身的实例传入setBeanFactory()
5.如果有一些BeanPostProcessor s关联了这个bean,调用postProcessBeforeInitialization()
6.InitializingBean的afterPropertiesSet(),这个方法在Bean的属性被全部设置后发出。
7.调用定制的初始化方法init-method
8.调用BeanPostProcessor s的postProcessAfterInitialization()
Note:6,7用于A,B属性注入之后,根据A,B还需要对一个内部属性C进行处理的场合。
一般6,7或任选一种方式,如果不想在xml里面定义可以采取6,如果不希望spring与pojo耦合,可以选择7.
Container is shutdown:
1.DisposableBean的destroy::这个接口定义了一个destroy()方法,这个方法在可以在Bean销毁时调用,比如可以做释放资源用。
2.调用destroy-method
BeanPostProcessor
需实现两个接口
1.postProcessBeforeInitialzation:bean的实例初始化之前调用
2.postProcessAfterInitialization:初始化之后调用
Example:
1)HelloBeanPostProcessor
package cmei.spring.beans;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
*
* @author cmei
* @since 2012.07.26
*
*/
public class HelloBeanPostProcessor implements BeanPostProcessor{
@Override
public Object postProcessAfterInitialization(Object arg0, String arg1)
throws BeansException {
System.out.println("called after spring bean's initialization:postProcessAfterInitialization");
System.out.println(arg0+" "+arg1);
return arg0;
}
@Override
public Object postProcessBeforeInitialization(Object arg0, String arg1)
throws BeansException {
System.out.println("called before spring bean's initialization:postProcessBeforeInitialization");
System.out.println(arg0+" "+arg1);
return arg0;
}
}
spring自带的BeanPostprocessors:
1.ApplicationContextAwareProcessor:为实现了ApplicationContextAware的接口的Beans设置application context。
BeanFactoryPostProcessor
需实现接口
1.postProcessBeanFactory:由spring container(beanFactory)在装载了
所有的bean的类定义之后Bean实例化之前调用。
应用:比如计算BeanCounter来计算所有装载到factory的bean类的数目。
example:
package cmei.spring.beans;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
public class HelloBeanFactoryPostProcessor implements BeanFactoryPostProcessor{
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)
throws BeansException {
System.out.println("called before all beans instantiate:postProcessBeanFactory");
System.out.println(arg0.getBeanDefinitionNames()+" "+arg0.getBeanDefinitionCount());
}
}
spring自带的BeanFactoryPostProcessors:
1.PropertyPlaceholderConfigurer
2.CustomEditorConfigurer
FactoryBean
1.FactoryBean本身是一个工程类
2.程序中需要的Bean可由该类负责产生,同样被自动注入spring context,并且可由context.getBean()获得实例。如要获取FactoryBean自身,需要加“&”。
3.若某个类的初始化或构造比较复杂的话(使用xml配置属性不方便),可以考虑使用一个FactoryBean来构造该类。
需实现三个方法:
1)Object getObject()
2)Class getObjectType()
3)boolean isSingleton()
常见的FactoryBean:org.mybatis.spring.SqlSessionFactoryBean
Example:
package cmei.spring.beans;
import java.security.MessageDigest;
import org.springframework.beans.factory.FactoryBean;
public class HelloFactoryBean implements FactoryBean<MessageDigest>{
private static final String DEFAULT_ALGORITH="MD5";
private static String algorithm=DEFAULT_ALGORITH;
@Override
public MessageDigest getObject() throws Exception {
return MessageDigest.getInstance(algorithm);
//this.algorithm;
}
@Override
public Class getObjectType() {
return MessageDigest.class;
}
@Override
public boolean isSingleton() {
return true;
}
public void setAlgorithm(String algorithm){
this.algorithm=algorithm;
}
}
附:
context config:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<context:component-scan base-package="cmei.spring.beans"></context:component-scan>
<bean id="helloBean" class="cmei.spring.beans.HelloBean" init-method="_init" destroy-method="_destroy">
<property name="msg"><value>hello world!</value></property>
</bean>
<bean class="cmei.spring.beans.HelloBeanPostProcessor"></bean>
<bean class="cmei.spring.beans.HelloBeanFactoryPostProcessor"></bean>
<bean id="sha" class="cmei.spring.beans.HelloFactoryBean">
<property name="algorithm" value="SHA1"></property>
</bean>
<bean id="md5" class="cmei.spring.beans.HelloFactoryBean"></bean>
</beans>
test:
HelloBean for test bean life cycle
package cmei.spring.beans;
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;
public class HelloBean implements BeanNameAware,BeanFactoryAware,InitializingBean,DisposableBean{
private String msg="";
private String id;
private BeanFactory beanFactory;
private static String ClassName="HelloBean";
{
System.out.println(msg);
System.out.println("instantiate initialization");
}
static{
System.out.println(ClassName);
System.out.println("static initialization");
}
public HelloBean(){
this.msg="msg";
System.out.println("bean instantiation:HelloBean()");
}
public void setMsg(String msg){
System.out.println("DI:HelloBean:setMsg()");
this.msg=msg;
}
public void sayHello(){
System.out.println(msg);
}
@Override
public void setBeanName(String name) {
System.out.println("setBeanName:"+name);
this.id=name;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("setBeanFactory"+beanFactory.toString());
this.beanFactory=beanFactory;
}
@Override
public void destroy() throws Exception {
System.out.println("Disposable Bean{'s destroy()");
}
public void _destroy(){
System.out.println("custom Bean{'s destroy()");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Initializating Bean's afterPropertiesSet()");
}
public void _init(){
System.out.println("custom Initializating Bean");
}
}
main:
package cmei.spring.beans;
import java.security.MessageDigest;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class BeanMain {
public static void main(String[] args){
ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
HelloBean helloBean=(HelloBean)context.getBean("helloBean");
helloBean.sayHello();
System.out.println("***********************************");
MessageDigest md5=(MessageDigest)context.getBean("md5");
System.out.println(md5.getAlgorithm());
MessageDigest sha=(MessageDigest)context.getBean("sha");
System.out.println(md5.getAlgorithm());
System.out.println("done.");
}
}
输入结果:
called before all beans instantiate:postProcessBeanFactory
[Ljava.lang.String;@679bfb30 9
HelloBean
static initialization
instantiate initialization
bean instantiation:HelloBean()
DI:HelloBean:setMsg()
setBeanName:helloBean
setBeanFactoryorg.springframework.beans.factory.support.DefaultListableBeanFactory@4839e5b5: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,helloBean,cmei.spring.beans.HelloBeanPostProcessor#0,cmei.spring.beans.HelloBeanFactoryPostProcessor#0,sha,md5]; root of factory hierarchy
called before spring bean's initialization:postProcessBeforeInitialization
cmei.spring.beans.HelloBean@1d766806 helloBean
Initializating Bean's afterPropertiesSet()
custom Initializating Bean
called after spring bean's initialization:postProcessAfterInitialization
cmei.spring.beans.HelloBean@1d766806 helloBean
called before spring bean's initialization:postProcessBeforeInitialization
cmei.spring.beans.HelloFactoryBean@48cbdb20 sha
called after spring bean's initialization:postProcessAfterInitialization
cmei.spring.beans.HelloFactoryBean@48cbdb20 sha
called before spring bean's initialization:postProcessBeforeInitialization
cmei.spring.beans.HelloFactoryBean@6de1dadb md5
called after spring bean's initialization:postProcessAfterInitialization
cmei.spring.beans.HelloFactoryBean@6de1dadb md5
hello world!
***********************************
called after spring bean's initialization:postProcessAfterInitialization
SHA1 Message Digest from SUN, <initialized>
md5
SHA1
called after spring bean's initialization:postProcessAfterInitialization
SHA1 Message Digest from SUN, <initialized>
sha
SHA1
done.
[Ljava.lang.String;@679bfb30 9
HelloBean
static initialization
instantiate initialization
bean instantiation:HelloBean()
DI:HelloBean:setMsg()
setBeanName:helloBean
setBeanFactoryorg.springframework.beans.factory.support.DefaultListableBeanFactory@4839e5b5: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,helloBean,cmei.spring.beans.HelloBeanPostProcessor#0,cmei.spring.beans.HelloBeanFactoryPostProcessor#0,sha,md5]; root of factory hierarchy
called before spring bean's initialization:postProcessBeforeInitialization
cmei.spring.beans.HelloBean@1d766806 helloBean
Initializating Bean's afterPropertiesSet()
custom Initializating Bean
called after spring bean's initialization:postProcessAfterInitialization
cmei.spring.beans.HelloBean@1d766806 helloBean
called before spring bean's initialization:postProcessBeforeInitialization
cmei.spring.beans.HelloFactoryBean@48cbdb20 sha
called after spring bean's initialization:postProcessAfterInitialization
cmei.spring.beans.HelloFactoryBean@48cbdb20 sha
called before spring bean's initialization:postProcessBeforeInitialization
cmei.spring.beans.HelloFactoryBean@6de1dadb md5
called after spring bean's initialization:postProcessAfterInitialization
cmei.spring.beans.HelloFactoryBean@6de1dadb md5
hello world!
***********************************
called after spring bean's initialization:postProcessAfterInitialization
SHA1 Message Digest from SUN, <initialized>
md5
SHA1
called after spring bean's initialization:postProcessAfterInitialization
SHA1 Message Digest from SUN, <initialized>
sha
SHA1
done.