Spring之bean的生命周期

Spring之bean的生命周期

在传统的Java应用中,bean的生命周期很简单,使用Java关键字 new 进行Bean 的实例化,然后该Bean 就能够使用了。一旦bean不再被使用,则由Java自动进行垃圾回收。

相比之下,Spring管理Bean的生命周期就复杂多了,正确理解Bean 的生命周期非常重要,因为Spring对Bean的管理可扩展性非常强,下面展示了一个Bean的构造过程

image

  1. Bean 容器找到配置文件中 Spring Bean 的定义。
  2. Bean 容器利用 Java Reflection API 创建一个 Bean 的实例。
  3. 如果涉及到一些属性值 利用 set()方法设置一些属性值。
  4. 如果实现了其他 *.Aware接口,就调用相应的方法。
  5. 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessBeforeInitialization() 方法
  6. 如果 Bean 实现了InitializingBean接口,执行afterPropertiesSet()方法。
  7. 如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。
  8. 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessAfterInitialization() 方法
  9. 当要销毁 Bean 的时候,如果 Bean 实现了 DisposableBean 接口,执行 destroy() 方法。
  10. 当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法。

BeanFactory 的注释里,有这么一段话,如下图所示:
image

代码演示

  1. 新建一个 User 类,让其实现接口 BeanNameAwareBeanFactoryAwareInitializingBeanDiposableBean 这4个接口,以及编写userInit()userDestroy() 两个方法,对应配置文件中 <bean>init-methoddestroy-method
package com.wqing.domain;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;

/**
 * @Description 用于演示 Bean 的生命周期
 * @Author wqing
 * @Date 2022/8/11 15:37
 */
public class User implements BeanNameAware, BeanFactoryAware,
        InitializingBean, DisposableBean {
    private String name;
    private Integer age;

    private BeanFactory beanFactory;
    private String beanName;

    public User() {
        System.out.println("[构造器]--调用User的构造函数进行实例化");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("[属性填充]--注入属性name");
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        System.out.println("[属性填充]--注入属性age");
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    //这是 BeanFactoryAware 接口的方法
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("[BeanFactoryAware]--执行BeanFactoryAware.setBeanFactory(),beanFactory为:" + beanFactory);
        this.beanFactory = beanFactory;
    }

    //这是 BeanNameAware 接口的方法
    @Override
    public void setBeanName(String name) {
        System.out.println("[BeanNameAware]--执行BeanNameAware.setBeanName(),beanName为: " + name);
        this.beanName = name;
    }

    //这是 DisposableBean 接口的方法
    @Override
    public void destroy() throws Exception {
        System.out.println("[DisposableBean]--执行DisposableBean.destroy()");
    }

    //这是 InitializingBean 接口的方法
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("[InitializingBean]--执行InitializingBean.afterPropertiesSet()");
    }

    // 通过<bean>的init-method属性指定的初始化方法
    public void userInit() {
        System.out.println("[init-method]--执行<bean>的init-method属性指定的初始化方法");
    }

    // 通过<bean>的destroy-method属性指定的初始化方法
    public void userDestroy() {
        System.out.println("[destroy-method]--执行<bean>的destroy-method属性指定的销毁方法");
    }
}

  1. 自定义 MyBeanPostProcessor 实现 BeanPostProcessor
package com.wqing.domain;

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

/**
 * @Description
 * @Author wqing
 * @Date 2022/8/11 16:06
 */
public class MyBeanPostProcessor implements BeanPostProcessor {
    /**
     * 实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("[BeanPostProcessor]--执行BeanPostProcessor.postProcessBeforeInitialization()");
        return bean;
    }

    /**
     * 实例化、依赖注入、初始化完毕时执行
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("[BeanPostProcessor]--执行BeanPostProcessor.postProcessAfterInitialization()");
        return bean;
    }
}

BeanPostProcessor 接口包括2个方法 postProcessAfterInitializationpostProcessBeforeInitialization,这两个方法的第一个参数都是要处理的Bean对象,第二个参数都是Bean的name。返回值也都是要处理的Bean对象。

  1. 编写 application.xml,将 UserMyBeanPostProcessor 注册进容器
<?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="user" class="com.wqing.domain.User" init-method="userInit"
          destroy-method="userDestroy">
        <property name="name" value="张三"/>
        <property name="age" value="20"/>
    </bean>

    <bean id="myBeanPostProcessor" class="com.wqing.domain.MyBeanPostProcessor"/>
</beans>
  1. 编写测试类
package com.wqing;

import com.wqing.domain.User;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Description
 * @Author wqing
 * @Date 2022/8/5 14:38
 */
public class Test {
    public static void main(String[] args) {
        System.out.println("容器开始创建");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        User bean = context.getBean(User.class);
        System.out.println("使用 bean");
        System.out.println(bean);
        System.out.println("容器开始销毁");
        context.close();
    }
}

执行结果

容器开始创建
[构造器]--调用User的构造函数进行实例化
[属性填充]--注入属性name
[属性填充]--注入属性age
[BeanNameAware]--执行BeanNameAware.setBeanName(),beanName为: user
[BeanFactoryAware]--执行BeanFactoryAware.setBeanFactory(),beanFactory为:org.springframework.beans.factory.support.DefaultListableBeanFactory@38082d64: defining beans [user,myBeanPostProcessor]; root of factory hierarchy
[BeanPostProcessor]--执行BeanPostProcessor.postProcessBeforeInitialization()
[InitializingBean]--执行InitializingBean.afterPropertiesSet()
[init-method]--执行<bean>的init-method属性指定的初始化方法
[BeanPostProcessor]--执行BeanPostProcessor.postProcessAfterInitialization()
使用 bean
User{name='张三', age=20}
容器开始销毁
[DisposableBean]--执行DisposableBean.destroy()
[destroy-method]--执行<bean>的destroy-method属性指定的销毁方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值