任意的对象都有创建,使用和销毁,使用Sping管理对象也是一样.所有Spring管理的Bean,默认都是singleton(单例)的,除非你指定是prototype类型的bean,如果是指定了这种类型,spring就不能帮助你管理bean的生命周期了.通过这种方法,你也可以把struts1的中的实例配置成多例.
spring 中配置的bean默认会自动初始化当你在加载对应的配置文件的时候, 你也可以通过<beans default-lazy-init="true" 或 <bean id="xx" lazy-init="true" 令其延迟加载.
如果想让spring支持Java 的@postConstruct and @preDestory, 你需要使用org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
如果需要container(容器)拦截其中任意bean的初始化过程,你可以实现BeanPostProcessor
接下来我们就来看看一个bean的管理过程
1. Call Constructor 调用构造函数.(如果没有配置constructor 属性,调用默认 无参数的构造函数(可以是private/protected/public))
2. 调用配置过的所有setter. (通过<protperty name="xxx" value=xxxx)
3. 调用Aware, 如果你实现了BeanNameAware/BeanFactoryAware/ApplicaitonContextAware接口的话
3.1 调用setBeanName
3.2 调用setBeanFactory
3.3 调用setApplicationContext
4. 调用postProcessBeforeInitialization方法,如果你有一个实现了BeanPostProcessor接口的bean的话
5. 调用@PostConstruct, 如果你引用了CommonAnnotationBeanPostProcessor
6. 调用afterPropertiesSet, 如果你的bean实现了InitializingBean接口
7. 调用init-method,配置在spring配置文件中.
8. 调用postProcessAfterInitialization,如果你有一个实现了BeanPostProcessor接口的bean的话
9. 调用@PreDestroy, 如果你引用了CommonAnnotationBeanPostProcessor 并且注册的shutDownHook或者是一个被托管的容器
10.调用destory-method,配置在spring配置文件中.
下面是具体实例的输出结果
1.Construct
2. setName - test
3. setBeanName called, bean need implements setBeanNameAware
setBeanFactory called, bean need implements setBeanFactoryAware
setApplicationContext called, bean need implements ApplicationContextAware
4. postProcessBeforeInitialization --Bean 'testBean' created : lifecycle.TestBean@12401369
5. @PostConstruct annotation called, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor registor requried.
6. afterPropertiesSet called, bean need implements InitializingBean
7. configed init Method in spring file called
8. postProcessAfterInitialization --
9. @PreDestroy annotation called, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor registor requried.
10. configed destory Method in spring file called
public class LifecycleTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] beanFiles = new String[]{"lifecycle/beans.xml"};
ApplicationContext appCxt = new ClassPathXmlApplicationContext(beanFiles);
((AbstractApplicationContext)appCxt).registerShutdownHook();
//(ClassPathXmlApplicationContext)appCxt)
}
}
<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"
xsi:schemaLocation="
http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="CommonAnnotationBeanPostProcessor"
class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
<bean id="testBean" class="lifecycle.TestBean" init-method="initMethod"
destroy-method="destroyMethod">
<property name="name" value="test"></property>
</bean>
<bean id="beanPostProcessor" class="lifecycle.TraceBeanPostProcessor">
</bean>
</beans>
public class TestBean implements BeanNameAware, BeanFactoryAware,
ApplicationContextAware, InitializingBean {
private TestBean() {
System.out.println("Construct");
}
@PostConstruct
public void postConstruct() {
System.out
.println("@PostConstruct annotation called, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor registor requried.");
}
@PreDestroy
public void preDestroy() {
System.out
.println("@PreDestroy annotation called, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor registor requried.");
}
public void initMethod() {
System.out.println(" configed init Method in spring file called");
}
public void destroyMethod() {
System.out.println(" configed destory Method in spring file called");
}
private String name;
public String getName() {
System.out.println("getName - " + name);
return name;
}
public void setName(String name) {
System.out.println("setName - " + name);
this.name = name;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out
.println("afterPropertiesSet called, bean need implements InitializingBean");
}
ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
System.out
.println(" setApplicationContext called, bean need implements ApplicationContextAware");
}
BeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
System.out
.println(" setBeanFactory called, bean need implements setBeanFactoryAware");
}
String beanName;
@Override
public void setBeanName(String beanName) {
this.beanName = beanName;
System.out
.println(" setBeanName called, bean need implements setBeanNameAware");
}
}
public class TraceBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println(" postProcessAfterInitialization --");
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println(" postProcessBeforeInitialization --" + "Bean '"
+ beanName + "' created : " + bean.toString());
return bean;
}
}