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

spring bean生命周期

2017-07-27 01:01 309 查看

BeanFactory中bean生命周期



如果容器注册了InstantiationAwareBeanPostProcessor接口,则在实例化bean之前,将调用接口的postProcessBeforeInstantiation()方法。

根据配置情况调用bean构造函数或工厂方法实例化Bean.

如果容器注册了InstantiationAwareBeanPostProcessor接口,则在实例化bean之后,将调用接口的postProcessAfterInstantiation()方法。

如果bean设置了属性信息,那么容器在这一步着手将配置值设置到Bean对应的属性中,不过在设置属性之前先调用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues方法。

调用bean的属性设置方法设置属性。

如果bean实现了BeanNameAware接口,那么将调用setBeanName()方法。

如果实现了BeanFactoryAware接口,则调用setBeanFactory()方法。

如果BeanFactory装配了BeanPostProcessor后处理器,则将调用BeanPostProcessor的postProcessBeforeInitialization方法。

如果Bean实现了InitializingBean,则调用afterPropertiesSet()方法。

如果在bean中通过init-method属性定义了初始化方法,则将执行这个方法。

调用BeanPostProcessor的postProcessAfterInitialization方法。

如果bean的scope为prototype,那么将bean的引用返回给调用者。调用者负责bean后续声明的管理,spring不再管理这个bean的声明周期。如果是singleton,那么bean放入spring ioc容器的缓冲池中。并将bean返回给调用者。

对于singleton bean,当容器关闭时,如果bean实现了DisposableBean接口,将调用此接口的destory()方法。

对于singleton bean,如果定义了destory-method属性,那么将调用这个方法。

方法分类

Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:

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

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

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

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

InstantiationAwareBeanPostProcessor其实为BeanPostProcessor的子接口,spring提供了一个适配器类BeanPostProcessorAdapter。一般继承这个类。

示例

public class Car implements BeanFactoryAware,BeanNameAware,InitializingBean,
DisposableBean{
private String brand;

public Car() {
System.out.println("调用car构造函数");
}

public void setBrand(String brand) {
System.out.println("调用setBrand()方法设置属性");
this.brand = brand;
}
public void myinit(){
System.out.println("init-methd invoke");
}
public void mydestroy(){
System.out.println("destroy-methd invoke");
}

@Override
public void destroy() throws Exception {
System.out.println("disposableBean.destroy()");
}

@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet");

}

@Override
public void setBeanName(String name) {
System.out.println("setBeanName");

}

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("setBeanFactory");

}

}
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter{

@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if("car".equals(beanName)){
System.out.println("InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation");
}
return null;
}

@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if("car".equals(beanName)){
System.out.println("InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation");
}
return true;
}

@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean,
String beanName) throws BeansException {
if("car".equals(beanName)){
System.out.println("InstantiationAwareBeanPostProcessor.postProcessPropertyValues");
}
return pvs;
}

}
public class MyBeanPostProcessor implements BeanPostProcessor{

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if("car".equals(beanName)){
System.out.println("BeanPostProcessor.postProcessBeforeInitialization");
}
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if("car".equals(beanName)){
System.out.println("BeanPostProcessor.postProcessAfterInitialization");
}
return bean;
}

}
public class BeanLifeCycleTest {
public static void main(String[] args) throws IOException {
Resource resource = new ClassPathResource("applicationContext.xml");
System.out.println(resource.getURL());
BeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader =
new XmlBeanDefinitionReader((DefaultListableBeanFactory)beanFactory);
reader.loadBeanDefinitions(resource);
((ConfigurableBeanFactory)beanFactory).addBeanPostProcessor(new MyBeanPostProcessor());
((ConfigurableBeanFactory)beanFactory).addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
Car car = (Car) beanFactory.getBean("car");

((DefaultListableBeanFactory)beanFactory).destroySingletons();

}
}


spring配置文件:

<bean id="car" class="com.topview.springBean.model.Car" init-method="myinit"
destroy-method="mydestroy">
<property name="brand" value="大众"></property>

</bean>


运行结果如下:

InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
调用car构造函数
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
InstantiationAwareBeanPostProcessor.postProcessPropertyValues
调用setBrand()方法设置属性
setBeanName
setBeanFactory
BeanPostProcessor.postProcessBeforeInitialization
afterPropertiesSet
init-methd invoke
BeanPostProcessor.postProcessAfterInitialization
disposableBean.destroy()
destroy-methd invoke


注:后处理器的实际调用顺序和注册顺序时无关 的。在具有多个后处理器的情况下,必须通过实现Ordered接口来确定调用顺序。

spring还拥有一个bean后置处理器InitDestroyAnnotationBeanPostProcessor,负责对标注了@PostConstruct,@PreDestroy的bean进行处理。(如果在applicationContext中,则已经默认装配了该处理器)

ApplicationContext中bean的生命周期

与Factory中的相似,不同的是如果bean实现了ApplicationContext接口,则会调用setApplicationContext方法。

如果配置文件中声明了工厂后处理器接口BeanFactoryPostProcessor的实现类,则应用上下文在装载配置文件之后,初始化bean实例之前将调用这些BeanFactoryPostProcessor对配置信息进行加工处理。工厂后处理器是容器级的,仅在应用上下文初始化时调用一次。

ApplicationContext与BeanFactory最大的不同在于,前者会利用java反射机制自动识别出配置文件中定义的后处理器,并自动将他们注册到应用上下文中。而后者需要通过代码手动注册。在ApplicationContext中,只需在配置文件中通过bean标签定义工厂后处理器和bean后处理器,它们就会按预期的方式进行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: