Spring 教程

Spring 笔记

original icon
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.knowledgedict.com/tutorial/spring_framework-bean-life-cycle.html

Spring Bean 生命周期


理解 Spring bean 的生命周期很容易。当一个 bean 被实例化时,它可能需要执行一些初始化使它转换成可用状态。同样,当 bean 不再需要,并且从容器中移除时,可能需要做一些清除工作。

生命周期流程图

Spring Bean 的完整生命周期从创建 Spring 容器开始,直到最终 Spring 容器销毁 Bean,这其中包含了一系列关键点。

spring bean 生命周期图1

spring bean 生命周期图2

示例

创建两个 bean,让其相互依赖。

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

public class BeanADemo implements ApplicationContextAware, BeanFactoryAware, BeanNameAware, BeanPostProcessor, DisposableBean, InitializingBean {

    private BeanBDemo beanBDemo;

    public BeanADemo() {
        System.out.println("Constructor BeanADemo invoked");
    }

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

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

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("ApplicationContextAware setApplicationContext invoked");
    }

    @PostConstruct
    public void postConstructMethod() {
        System.out.println("Post Construct BeanADemo invoked");
    }

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

    public void initMethod() {
        System.out.println("init-method BeanADemo invoked");
    }

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

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

    @PreDestroy
    public void preDestroyMethod() {
        System.out.println("Pre Destroy BeanADemo invoked");
    }

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

    public void destroyMethod() {
        System.out.println("destroy-method BeanADemo invoked");
    }

    @Resource
    public void setBeanBDemo(BeanBDemo beanBDemo) {
        System.out.println("setBeanBDemo invoked");
        this.beanBDemo = beanBDemo;
    }
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

public class BeanBDemo implements ApplicationContextAware, BeanFactoryAware, BeanNameAware, BeanPostProcessor, DisposableBean, InitializingBean {

    private BeanADemo beanADemo;

    public BeanBDemo() {
        System.out.println("Constructor BeanBDemo invoked");
    }

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

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

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("ApplicationContextAware setApplicationContext invoked");
    }

    @PostConstruct
    public void postConstructMethod() {
        System.out.println("Post Construct BeanBDemo invoked");
    }

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

    public void initMethod() {
        System.out.println("init-method BeanBDemo invoked");
    }

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

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

    @PreDestroy
    public void preDestroyMethod() {
        System.out.println("Pre Destroy BeanBDemo invoked");
    }

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

    public void destroyMethod() {
        System.out.println("destroy-method BeanBDemo invoked");
    }

    @Resource
    public void setBeanADemo(BeanADemo beanADemo) {
        System.out.println("setBeanADemo invoked");
        this.beanADemo = beanADemo;
    }
}

通过 xml 配置 bean。 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启基于注解的配置 -->
    <context:annotation-config/>

    <bean class="demo.BeanADemo" init-method="initMethod" destroy-method="destroyMethod"/>

    <bean class="demo.BeanBDemo" init-method="initMethod" destroy-method="destroyMethod"/>

</beans>

启动 Spring 容器及关闭。

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo {

    public static void main(String[] args) {

        ClassPathXmlApplicationContext ct = new ClassPathXmlApplicationContext("demo.xml");
        ct.close();
    }

}

执行结果如下:

Constructor BeanADemo invoked
Constructor BeanBDemo invoked
setBeanADemo invoked
setBeanName demo.BeanBDemo#0 invoked
setBeanFactory B invoked
ApplicationContextAware setApplicationContext invoked
Post Construct BeanBDemo invoked
InitializingBean afterPropertiesSet BeanBDemo invoked
init-method BeanBDemo invoked
setBeanBDemo invoked
setBeanName demo.BeanADemo#0 invoked
setBeanFactory invoked
ApplicationContextAware setApplicationContext invoked
Post Construct BeanADemo invoked
InitializingBean afterPropertiesSet BeanADemo invoked
init-method BeanADemo invoked
BeanPostProcessor postProcessBeforeInitialization BeanADemo invoked
BeanPostProcessor postProcessBeforeInitialization BeanBDemo invoked
BeanPostProcessor postProcessAfterInitialization BeanADemo invoked
BeanPostProcessor postProcessAfterInitialization BeanBDemo invoked
BeanPostProcessor postProcessBeforeInitialization BeanADemo invoked
BeanPostProcessor postProcessBeforeInitialization BeanBDemo invoked
BeanPostProcessor postProcessAfterInitialization BeanADemo invoked
BeanPostProcessor postProcessAfterInitialization BeanBDemo invoked
Pre Destroy BeanBDemo invoked
DisposableBean destroy BeanBDemo invoked
destroy-method BeanBDemo invoked
Pre Destroy BeanADemo invoked
DisposableBean destroy BeanADemo invoked
destroy-method BeanADemo invoked

可以得知,Spring IoC 容器中 bean 的初始化,首先调用所有 bean 的构造器,然后针对一个 bean 进行相应的初始化顺序,具体如下:

初始化时:构造器 Construct -> 属性注入 -> BeanNameAware 接口实现方法 -> BeanFactoryAware 接口实现方法 -> ApplicationContextAware 接口实现方法 -> @PostConstruct -> InitializingBean 接口实现方法 -> bean 定义的 initMethod;

销毁时:@PreDestroy -> DisposableBean 接口实现方法 -> bean 定义的 destoryMethod。

Spring bean 对象是构成应用程序的支柱,也是由 Spring IoC 容器管理的。bean 是一个被实例化,组装,并通过 Spri ...
Django是一个基于Python的Web框架,它遵循着一套请求-响应的生命周期流程来处理客户端发起的HTTP请求。视图函数接收一个`Htt ...
生命周期和插件也是 Maven 的核心概念,我们的日常 Maven 命令行输入都对应生命周期,Maven 的生命周期是抽象的概念,其实际操作 ...
Spring 是最受欢迎的企业级 Java 应用程序开发框架,它目前由大量提供一系列服务的模块组成,几乎成了 Java 后端的标准开发框架。 ...
Django是一个基于Python的高级Web框架,它的请求生命周期可以分为以下几个阶段:URL解析、中间件处理、视图函数调用、模板渲染和响 ...