Spring 框架中,容器可以对 Singleton 作用域下的 bean 进行生命周期管理,对 bean 的创建、初始化和销毁进行控制。本文讲述 bean 的生命周期全过程,详细描述了生命周期过程中 spring 开放的自定义切入接口。

生命周期流程图:

Bean生命周期全过程

一、定义Bean

在程序启动最初,Spring 可通过 xml 文件、注解或 javaApi 的方式创建 BeanDefinition

BeanFactoryPostProcessorbean 工厂的后置处理器,在 BeanDefinition 全部扫描创建完成后执行,可以在容器的 bean 创建之前修改 bean 工厂和 BeanDefinition

二、实例化与属性注入

当客户向容器请求一个尚未初始化的 bean 时,或初始化 bean 时需要注入另一个尚末初始化的依赖时,容器就会调用 doCreateBean 方法通过反射的方式创建出一个 bean 对象。

bean 实例创建之后,doCreateBean 方法通过调用 populateBean 方法对这个 bean 进行属性填充。

三、初始化Bean

Bean 初始化过程对应 initializeBean 方法,将被 doCreateBean 方法调用。

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    // 执行 BeanNameAware、BeanClassLoaderAware和BeanFactoryAware
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean);
			return null;
		}, getAccessControlContext());
	}
	else {
		invokeAwareMethods(beanName, bean);
	}
	Object wrappedBean = bean;
    // 执行 BeanPostProcessor 接口的 postProcessBeforeInitialization 方法。
    // 除了上述的三个 Aware 接口,其余的 Aware 接口通过 BeanPostProcessor 接口实现,具体实现类为
    // ApplicationContextAwareProcessor。
    // 初始化 bean 的扩展插入注解 @PostConstruct 通过 CommonAnnotationBeanPostProcessor
    // 接口实现。
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}
    // 执行 InitializingBean 接口和 init-method 参数两种扩展方式插入的方法
	try {
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				(mbd != null ? mbd.getResourceDescription() : null),
				beanName, "Invocation of init method failed", ex);
	}
    // 执行 BeanPostProcessor 接口的 postProcessAfterInitialization 方法
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}
	return wrappedBean;
}

如上源码所示:

  1. 初始化 bean 最初,容器会检测 bean 是否实现了内置的 xxxAware 接口,如果实现了则执行相应的接口方法。

    通过 xxxAware 接口,可以让 bean 拿到 Spring 容器的一些资源。

    常见 Aware 接口:

    • ApplicationContextAware:获取容器本身 ApplicationContext 对象;
    • ApplicationEventPublisherAware:获取事件发布器的接口;
    • BeanClassLoaderAware:获取加载当前 bean 的类加载器;
    • BeanFactoryAware: 获取当前 beanBeanFactory 实例,可以用来手动注册 bean
    • BeanNameAware:在获取 bean 在容器中的的名称;
    • ResourceLoaderAware:获取 ResourceLoader 实例,获取资源加载器读取资源文件。
  2. 在执行完 BeanNameAwareBeanClassLoaderAwareBeanFactoryAware 之后,执行初始化扩展之前,spring 执行 BeanPostProcessor 后置处理器的 postProcessBeforeInitialization 方法。

    值得注意的是,Aware 、初始化扩展方法与 BeanPostProcessor 职责并非明确划分的,他们也通过 BeanPostProcessor 实现功能。

    除了上述的三种 Aware 接口,其余的 Aware 接口都是通过 BeanPostProcessor 的实现类 ApplicationContextAwareProcessor 在此处完成的调用。

    初始化扩展注解 @PostConstruct 通过 CommonAnnotationBeanPostProcessor 实现。

    通过控制 BeanPostProcessor 列表的顺序,从而使初始化的执行步骤有序。

BeanPostProcessor 列表

  1. 在初始化 beanspring 提供了三种扩展方式,三种扩展方式可同时使用,但不能同时指向同一个方法,多个扩展指向同一个方法这个方法也只会执行一次。

    扩展方法执行顺序为:@PostConstruct 注解 -> InitializingBean 接口 -> init-method 参数指定。

  2. 在执行自定义初始化方法之后,spring 最后执行 BeanPostProcessor 后置处理器的 postProcessAfterInitialization 方法,完成 bean 的初始化过程。

四、销毁Bean

在销毁 beanspring 提供了三种扩展方式,三种扩展方式可同时使用,但不能同时指向同一个方法,多个扩展指向同一个方法这个方法也只会执行一次。

扩展方法执行顺序为:@PreDestroy 注解 -> DisposableBean 接口 -> destroy-method 参数指定。

五、测试代码

BeanProcess 实体类:

package com.nineya.spring.bean.lifecycle.entity;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;

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

@Getter
@Setter
@ToString
public class BeanProcess implements BeanNameAware, ResourceLoaderAware, InitializingBean, DisposableBean {
    private String name;
    
    @PostConstruct
    public void init() {
        System.out.println("Bean @PostConstruct: name = " + name);
    }

    @PostConstruct
    public void init2() {
        System.out.println("Bean @PostConstruct2: name = " + name);
    }

    @PreDestroy
    public void preDestroy() {
        System.out.println("Bean @PreDestroy: name = " + name);
    }

    @PreDestroy
    public void preDestroy2() {
        System.out.println("Bean @PreDestroy2: name = " + name);
    }

    @Override
    public void destroy() {
        System.out.println("Bean DisposableBean: name = " + name);
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("Bean InitializingBean: name = " + name);
    }
    
    public void initMethod() {
        System.out.println("Bean InitMethod: name = " + name);
    }
    
    public void destroyMethod() {
        System.out.println("Bean DestroyMethod: name = " + name);
    }

    @Override
    public void setBeanName(String beanName) {
        System.out.println("Bean BeanNameAware: beanName = " + beanName + ", name = " + name);
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        System.out.println("Bean ResourceLoaderAware: resourceLoader = " + resourceLoader + ", name = " + name);
    }
}

NineyaBeanFactoryPostProcessor 后置处理器:

package com.nineya.spring.bean.lifecycle.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

@Component
public class NineyaBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("后置处理器BeanFactoryPostProcessor: postProcessBeanFactory: " + String.join(",", beanFactory.getBeanDefinitionNames()));
    }
}

NineyaBeanPostProcessor 后置处理器:

package com.nineya.spring.bean.lifecycle.processor;

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

@Component
public class NineyaBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("后置处理器BeanPostProcessor: postProcessAfterInitialization(" + beanName + ") :" + bean);
        return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("后置处理器BeanPostProcessor: postProcessBeforeInitialization(" + beanName + ") :" + bean);
        return bean;
    }
}

BeanLifecycleConfiguration 配置类:

package com.nineya.spring.bean.lifecycle.config;


import com.nineya.spring.bean.lifecycle.entity.BeanProcess;
import com.nineya.spring.bean.lifecycle.processor.NineyaBeanFactoryPostProcessor;
import com.nineya.spring.bean.lifecycle.processor.NineyaBeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BeanLifecycleConfiguration {
    @Bean(value = "test", initMethod = "initMethod", destroyMethod = "destroyMethod")
    public BeanProcess beanProcess() {
        BeanProcess beanProcess = new BeanProcess();
        beanProcess.setName("test");
        return beanProcess;
    }

    @Bean
    public NineyaBeanPostProcessor nineyaBeanPostProcessor() {
        return new NineyaBeanPostProcessor();
    }

    @Bean
    public NineyaBeanFactoryPostProcessor nineyaBeanFactoryPostProcessor() {
        return new NineyaBeanFactoryPostProcessor();
    }
}

入口类:

package com.nineya.spring.bean.lifecycle;

import com.nineya.spring.bean.lifecycle.entity.BeanProcess;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class BeanLifecycleMain {

    public static void main(String[] args) {
        System.out.println("## 创建容器");
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        System.out.println("## 扫描Bean注解");
        context.scan(BeanLifecycleMain.class.getPackage().getName());
        context.refresh();

        System.out.println("## 通过class取得bean");
        BeanProcess beanProcess = context.getBean(BeanProcess.class);
        System.out.println(beanProcess + " : " + beanProcess.hashCode());

        System.out.println("## 通过bean名称取得bean");
        beanProcess = (BeanProcess) context.getBean("test");
        System.out.println(beanProcess + " : " + beanProcess.hashCode());

        System.out.println("## 销毁Bean");
        ((DefaultListableBeanFactory)context.getBeanFactory()).destroySingleton("test");

        System.out.println("## 取得beanDefinition");
        BeanDefinition beanDefinition = context.getBeanFactory().getBeanDefinition("test");
        System.out.println("beanDefinition : " + beanDefinition);

        System.out.println("## 通过bean名称取得bean");
        beanProcess = (BeanProcess) context.getBean("test");
        System.out.println(beanProcess + " : " + beanProcess.hashCode());
    }
}

执行结果可反应上述生命周期过程:

## 创建容器
## 扫描Bean注解
后置处理器BeanFactoryPostProcessor: postProcessBeanFactory: org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,beanLifecycleConfiguration,nineyaBeanFactoryPostProcessor,nineyaBeanPostProcessor,test
Bean BeanNameAware: beanName = test, name = test
Bean ResourceLoaderAware: resourceLoader = org.springframework.context.annotation.AnnotationConfigApplicationContext@31cefde0, started on Tue Aug 08 15:47:54 CST 2023, name = test
后置处理器BeanPostProcessor: postProcessBeforeInitialization(test) :BeanProcess(name=test)
Bean @PostConstruct: name = test
Bean @PostConstruct2: name = test
Bean InitializingBean: name = test
Bean InitMethod: name = test
后置处理器BeanPostProcessor: postProcessAfterInitialization(test) :BeanProcess(name=test)
## 通过class取得bean
BeanProcess(name=test) : 346224929
## 通过bean名称取得bean
BeanProcess(name=test) : 346224929
## 销毁Bean
Bean @PreDestroy2: name = test
Bean @PreDestroy: name = test
Bean DisposableBean: name = test
Bean DestroyMethod: name = test
## 取得beanDefinition
beanDefinition : Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=beanLifecycleConfiguration; factoryMethodName=beanProcess; initMethodName=initMethod; destroyMethodName=destroyMethod; defined in com.nineya.spring.bean.lifecycle.config.BeanLifecycleConfiguration
## 通过bean名称取得bean
Bean BeanNameAware: beanName = test, name = test
Bean ResourceLoaderAware: resourceLoader = org.springframework.context.annotation.AnnotationConfigApplicationContext@31cefde0, started on Tue Aug 08 15:47:54 CST 2023, name = test
后置处理器BeanPostProcessor: postProcessBeforeInitialization(test) :BeanProcess(name=test)
Bean @PostConstruct: name = test
Bean @PostConstruct2: name = test
Bean InitializingBean: name = test
Bean InitMethod: name = test
后置处理器BeanPostProcessor: postProcessAfterInitialization(test) :BeanProcess(name=test)
BeanProcess(name=test) : 63468833