Spring Bean的生命周期

Spring Bean的生命周期,就是一个Bean在IOC容器中从创建到销毁的过程

1、生命周期概要流程

简单来说,一个Bean的生命周期分为四个阶段:

  1. 实例化(Instantiation)

  2. 属性设置(populate)

  3. 初始化(Initialization)

  4. 销毁(Destruction)

 具体逻辑位于AbstractAutowireCapableBeanFactorydoCreateBean方法中,代码较多,只放出了重要的部分,如下:

// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {
 
    // 1. 实例化
    BeanWrapper instanceWrapper = null;
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
   
    Object exposedObject = bean;
    try {
        // 2. 属性赋值
        populateBean(beanName, mbd, instanceWrapper);
        // 3. 初始化
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
 
    // 4. 销毁-注册回调接口
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
 
    return exposedObject;
}

        上面的实例化、属性赋值、初始化都是Spring容器启动时的步骤,销毁是在容器关闭时的操作,容器销毁时会调用容器的close()方法去销毁容器。

2、对生命周期的扩展

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

类型描述作用范围
Bean自身的方法这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法初始化之前,销毁之前
容器级生命周期接口方法这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。==作用于所有Bean的接口==对象初始化前后
工厂后处理器接口方法这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。实例化对象之前
Bean级生命周期接口方法这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法,==作用于单个Bean的接口,需要每个bean单击实现接口==对象初始化之前

 加上这些扩展,现在上面的图可以变成下面这样了:

3、Bean自身的方法

Bean自身的方法包括了Bean本身调用的方法和通过配置文件中<bean>的init-methoddestroy-method指定的方法

  • 创建实体类
public class Person {
    private String name;
    private String address;
    private String phone;
    public Person() {
        System.out.println("【构造器】调用Person的构造器实例化");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("【注入属性】注入属性name");
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        System.out.println("【注入属性】注入属性address");
        this.address = address;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        System.out.println("【注入属性】注入属性phone");
        this.phone = phone;
    }
    // 通过<bean>的init-method属性指定的初始化方法
    public void myInit() {
        System.out.println("【init-method】调用<bean>的init-method属性指定的初始化方法");
    }

    // 通过<bean>的destroy-method属性指定的初始化方法
    public void myDestory() {
        System.out.println("【destroy-method】调用<bean>的destroy-method属性指定的初始化方法");
    }
}
  • 配置文件如下
 <bean id="person" class="com.XXX.entity.Person" init-method="myInit" destroy-method="myDestory" scope="singleton" >
  <property name="name" value="tom"/>
  <property name="address" value="西安"/>
  <property name="phone" value="13800000000"/>
 </bean>
  • main方法测试
System.out.println("现在开始初始化容器");
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
        System.out.println("容器初始化成功");
        //得到Preson,并使用
        Person person = ac.getBean("person",Person.class);
        System.out.println(person);
        System.out.println("现在开始关闭容器!");
        ((ClassPathXmlApplicationContext)ac).registerShutdownHook();
  • 结果

4、容器级生命周期接口方法

 BeanPostProcessor接口包括2个方法:

postProcessAfterInitializationpostProcessBeforeInitialization,

这两个方法的第一个参数都是要处理的Bean对象,第二个参数都是Bean的name。

  • BeanPostProcessor

BeanPostProcessor作用在对象初始化之前后  

 定义类实现BeanPostProcessor

public class MyBeanPostProcessor implements BeanPostProcessor {
 
     public MyBeanPostProcessor() {
         super();
         System.out.println("这是BeanPostProcessor实现类构造器!!");
         // TODO Auto-generated constructor stub
     }
 
     @Override
     public Object postProcessAfterInitialization(Object arg0, String arg1)
             throws BeansException {
        String str = bean.getClass().getName();//通过反射,我们可以得到当前加载的类的信息
        System.out.println(str);//输出类的名称
         System.out
         .println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!");
         return arg0;
     }
 
     @Override
     public Object postProcessBeforeInitialization(Object arg0, String arg1)
             throws BeansException {
         System.out
         .println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!");
         return arg0;
     }
}

xml文件配置

<bean id="myBeanPostProcessor" class="com.XXX.config.MyBeanPostProcessor"/>

测试结果如下

 由于这里只配置了一个Person,所以只看Person的效果,如果配置了多个bean,都可以看到效果

  • InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor 作用对象实例化前后

InstantiationAwareBeanPostProcessor 接口本质是BeanPostProcessor的子接口,如下:

public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    public MyInstantiationAwareBeanPostProcessor() {
        super();
        System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!");
    }
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法");
        return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor调用postProcessAfterInstantiation方法");
        return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean, beanName);
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor调用postProcessProperties方法");
        return InstantiationAwareBeanPostProcessor.super.postProcessProperties(pvs, bean, beanName);
    }
}

配置文件

 <bean id="myInstantiationAwareBeanPostProcessor" 
class="com.XXX.config.MyInstantiationAwareBeanPostProcessor">
</bean>

测试结果如下

5、工厂后处理器接口方法

在初始化之前执行,演示工厂后处理器接口方法,如下:

MyBeanFactoryPostProcessor

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    public MyBeanFactoryPostProcessor() {
        super();
        System.out.println("这是BeanFactoryPostProcessor实现类构造器!!");
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) throws BeansException {
        System.out.println("BeanFactoryPostProcessor调用postProcessBeanFactory方法");
        BeanDefinition bd = arg0.getBeanDefinition("person");
        bd.getPropertyValues().addPropertyValue("phone", "110");
    }
}

配置文件

<bean id="beanFactoryPostProcessor"
 class="com.XXX.config.MyBeanFactoryPostProcessor"></bean>

测试结果

6、Bean级生命周期接口方法

 在初化对象之前 ,可以让实体类实现BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这4个接口

修改Person类结构,直接实现上面对应的接口

public class Person implements BeanFactoryAware, BeanNameAware,
        InitializingBean, DisposableBean {
    private String name;
    private String address;
    private String phone;
    private BeanFactory beanFactory;
    private String beanName;
    public Person() {
        System.out.println("【构造器】调用Person的构造器实例化");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("【注入属性】注入属性name");
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        System.out.println("【注入属性】注入属性address");
        this.address = address;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        System.out.println("【注入属性】注入属性phone");
        this.phone = phone;
    }
    // 通过<bean>的init-method属性指定的初始化方法
    public void myInit() {
        System.out.println("【init-method】调用<bean>的init-method属性指定的初始化方法");
    }

    // 通过<bean>的destroy-method属性指定的初始化方法
    public void myDestory() {
        System.out.println("【destroy-method】调用<bean>的destroy-method属性指定的初始化方法");
    }
    // 这是BeanFactoryAware接口方法
    @Override
    public void setBeanFactory(BeanFactory arg0) throws BeansException {
        System.out.println("【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()");
        this.beanFactory = arg0;
    }

    // 这是BeanNameAware接口方法
    @Override
    public void setBeanName(String arg0) {
        System.out.println("【BeanNameAware接口】调用BeanNameAware.setBeanName()");
        this.beanName = arg0;
    }

    // 这是InitializingBean接口方法
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()");
    }

    // 这是DiposibleBean接口方法
    @Override
    public void destroy() throws Exception {
        System.out.println("【DiposibleBean接口】调用DiposibleBean.destory()");
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", phone='" + phone + '\'' +
                ", beanFactory=" + beanFactory +
                ", beanName='" + beanName + '\'' +
                '}';
    }
}

测试结果如下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值