【java spring】bean的生命周期

bean的生命周期如下(原文:http://c.biancheng.net/spring/bean-life-cycle.html):
1、Spring 启动,查找并加载需要被 Spring 管理的 Bean,并实例化 Bean。
2、利用依赖注入完成 Bean 中所有属性值的配置注入。
3、如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。
4、如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。
5、如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
6、如果 Bean 实现了 BeanPostProcessor 接口,则 Spring 调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。
7、如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。
8、如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。
9、如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。
10、如果在 中指定了该 Bean 的作用域为 singleton,则将该 Bean 放入 Spring IoC 的缓存池中,触发 Spring 对该 Bean 的生命周期管理;如果在 中指定了该 Bean 的作用域为 prototype,则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。
11、如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法销毁 Bean;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁。

下面我们实际测试一下:
首先定义life_cycle_life.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="lifeTimeTestBean" class="upc.yqs.BeanLifeTime" init-method="initMethod">
    </bean>
    <bean class="upc.yqs.BeanLifeTimeInit1"></bean>
    <bean class="upc.yqs.BeanLifeTimeInit2"></bean>
</beans>

然后定义xml中相关联的类:

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;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class BeanLifeTime implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean
{
    @Override
    public void setBeanName(String s) {
        System.out.println("调用了setBeanName,传入了"+s);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("调用了setBeanFactory,传入了"+beanFactory);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("调用了setApplicationContext,传入了"+applicationContext);
    }

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

    public void initMethod() {
        System.out.println("调用了initMethod");
    }

    public void commonMethod()
    {
        System.out.println("调用了commonMethod");
    }
}

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;

public class BeanLifeTimeInit1 implements BeanPostProcessor, Ordered
{
    @Override
    public int getOrder() {
        return 0;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("调用了postProcessBeforeInitialization1,传入了"+beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("调用了postProcessAfterInitialization1,传入了"+beanName);
        return bean;
    }
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;

public class BeanLifeTimeInit2 implements BeanPostProcessor, Ordered
{
    @Override
    public int getOrder() {
        return 1;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("调用了postProcessBeforeInitialization2,传入了"+beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("调用了postProcessAfterInitialization2,传入了"+beanName);
        return bean;
    }
}

之后我们定义测试方法:

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class LifeTimeTest
{
    ApplicationContext context;

    @Before
    public void getContext() {
        context = new ClassPathXmlApplicationContext("life_cycle_test_beans.xml");
    }

    @Test
    public void lifeTimeTest()
    {
        BeanLifeTime bean=(BeanLifeTime) context.getBean("lifeTimeTestBean");
        bean.commonMethod();
    }
}

运行测试方法输出:
调用了setBeanName,传入了lifeTimeTestBean
调用了setBeanFactory,传入了org.springframework.beans.factory.support.DefaultListableBeanFactory@70be0a2b: defining beans [lifeTimeTestBean,upc.yqs.BeanLifeTimeInit1#0,upc.yqs.BeanLifeTimeInit2#0]; root of factory hierarchy
调用了setApplicationContext,传入了org.springframework.context.support.ClassPathXmlApplicationContext@6615435c, started on Sat Dec 18 16:18:58 CST 2021
调用了postProcessBeforeInitialization1,传入了lifeTimeTestBean
调用了postProcessBeforeInitialization2,传入了lifeTimeTestBean
调用了afterPropertiesSet
调用了initMethod
调用了postProcessAfterInitialization1,传入了lifeTimeTestBean
调用了postProcessAfterInitialization2,传入了lifeTimeTestBean
调用了commonMethod

Process finished with exit code 0

这里为什么先调用postProcessBeforeInitialization1后调用postProcessBeforeInitialization2呢,因为我们在定义BeanLifeTimeInit1和BeanLifeTimeInit2类的时候实现了Ordered接口,这个接口返回一个int值,越小的会越优先被执行,这里我们BeanLifeTimeInit1返回了0,BeanLifeTimeInit2返回了1,所以BeanLifeTimeInit1的优先级高。

至于为什么不像其它接口一样直接在BeanLifeTime类中实现而是单独写了一个类,是因为这个接口的特殊性。BeanPostProcessor 接口也被称为后置处理器,通过该接口可以自定义调用初始化前后执行的操作方法。所以写到一个单独的类里面会更加灵活,而且这样子可以写多个后置处理器。如果我们在BeanLifeTime类中实现这个接口,那么会导致后置处理器失效(包括其它所有的后置处理器,我试了是这样子的,有误请指出),所以显然spring不希望我们这么做。详细见:http://c.biancheng.net/spring/bean-post-processor.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值