玖叶教程网

前端编程开发入门

Spring 中 Bean的生命周期源码分析

Bean声明周期

在 Spring 中,Bean 的声明周期主要包括以下阶段:

1. 实例化(Instantiation):

在这个阶段,Spring 容器根据配置或者注解的方式,使用类的构造函数创建 Bean 的实例。

2. 属性赋值(Property Setting):

在实例化后,Spring 容器会将配置的属性值或通过依赖注入的方式,将属性值赋给 Bean 实例的对应属性。

3. 初始化(Initialization):

初始化阶段中,可以通过以下方式进行自定义逻辑:

- 实现 InitializingBean 接口,并覆盖其中的 afterPropertiesSet 方法;

- 在配置文件中使用 init-method 属性指定自定义的初始化方法;

- 使用 @PostConstruct 注解指定初始化方法。

4. 使用(In Use):

Bean 实例在容器中处于可用状态,可以被其他组件或者业务逻辑使用。

5. 销毁(Destruction):

销毁阶段分为显式和隐式两种方式:

- 显式销毁:可以通过以下方式进行自定义逻辑:

- 实现 DisposableBean 接口,并覆盖其中的 destroy 方法;

- 在配置文件中使用 destroy-method 属性指定自定义的销毁方法;

- 使用 @PreDestroy 注解指定销毁方法。

- 隐式销毁:当 Spring 容器关闭时,会自动调用销毁方法对 Bean 实例进行清理操作。

需要注意的是,对于单例范围(Singleton)的 Bean,默认情况下 Spring 容器会在容器初始化时实例化单例 Bean,并在容器关闭时销毁单例 Bean。而对于原型范围(Prototype)的 Bean,Spring 容器只负责实例化和属性赋值,具体的销毁操作需要由使用者自行管理。

通过实现 InitializingBean 和 DisposableBean 接口、配置 init-method 和 destroy-method 方法,以及使用注解的方式,开发者可以在 Bean 的声明周期的不同阶段进行自定义的初始化和销毁操作。在这些阶段中,开发者可以根据需要执行相应的业务逻辑,进行资源的获取和释放,或者其他一些自定义的操作。

Bean生命周期实现的原理

Bean创建过程的步骤是确定的,因此,在Bean创建步骤节点的前后可以对Bean进行修改编辑。

本质使用了模版设计模式节点集合增强的方式。

public interface BeanPostProcessor {
  	void inject(Object bean);
}


p class MyBeanFactory {
    public Object getBean() {
        Object bean = new Object();
        System.out.println("构造 " + bean);
        System.out.println("依赖注入 " + bean);
        for (BeanPostProcessor processor : processors) {
            processor.inject(bean);
        }
        System.out.println("初始化 " + bean);
        return bean;
    }

    private List<BeanPostProcessor> processors = new ArrayList<>();

    public void addProcessor(BeanPostProcessor processor) {
        processors.add(processor);
    }
}

public static void main(String[] args) {
    MyBeanFactory beanFactory = new MyBeanFactory();
    beanFactory.addProcessor(bean -> System.out.println("解析 @Autowired"));
    beanFactory.addProcessor(bean -> System.out.println("解析 @Resource"));
    beanFactory.getBean();
}

上面的代码,完整阐述了BeanPostProcessor的实现原理。

Bean生命周期源码分析

InstantiationAwareBeanPostProcessor和DestructionAwareBeanPostProcessor都继承了BeanPostProcessor。

接口

功能描述

BeanPostProcessor

初始前后对 Bean 进行额外的处理、修改或增强

InstantiationAwareBeanPostProcessor

Bean实例化之前后调用,自定义的Bean实例。
属性赋值之前调用,自定义的属性对象。

DestructionAwareBeanPostProcessor

销毁阶段的回调方法


后置处理器被调用的源码

AbstractAutowireCapableBeanFactory 类中完成Bean创建。

applyBeanPostProcessorsBeforeInstantiation()方法中调用postProcessBeforeInstantiation()。

Bean实例化之前调用(postProcessBeforeInstantiation())

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
			Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
			if (result != null) {
				return result;
			}
		}
		return null;
	}

Bean实例化之后调用(postProcessAfterInstantiation())

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
	  ...

		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
		// state of the bean before properties are set. This can be used, for example,
		// to support styles of field injection.
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}
 .... 
}

属性注入之前(postProcessProperties())

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		......
		if (hasInstantiationAwareBeanPostProcessors()) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					return;
				}
				pvs = pvsToUse;
			}
		}
 .......
}

初始化之前(postProcessBeforeInitialization())

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

初始化之后(postProcessAfterInitialization())

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

销毁之前(postProcessBeforeDestruction()) 单例bean的销毁之前

protected void destroySingleton(String beanName) {
    // 获取单例bean实例
    Object singletonInstance = this.singletonObjects.get(beanName);

    // 检查是否是DestructionAwareBeanPostProcessor的实现类
    if (singletonInstance instanceof DestructionAwareBeanPostProcessor) {
        DestructionAwareBeanPostProcessor processor = (DestructionAwareBeanPostProcessor) singletonInstance;
        
        // 调用postProcessBeforeDestruction方法
        processor.postProcessBeforeDestruction(singletonInstance, beanName);
    }

    // 移除该单例bean
    // ...
}


Bean的生命周期各阶段都是由BeanPostProcessor提供增强的。

BeanPostProcessor是 Spring 框架中的一个扩展接口,可以用于在 Bean 的初始化前后进行自定义处理。它允许开发者在 Bean 实例化和初始化的过程中插入自定义逻辑,对 Bean 进行修改、增强或替换。

具体来说,BeanPostProcessor接口定义了以下两个方法:

  1. postProcessBeforeInitialization
    在 Bean 初始化之前调用。可以在此方法中对 Bean 进行额外的处理、修改或增强。
  2. postProcessAfterInitialization
    在 Bean 初始化之后调用。可以在此方法中对 Bean 进行额外的处理、修改或增强。


InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor是Spring框架中的一个扩展接口,它继承了BeanPostProcessor接口,并添加了Bean实例化之前、Bean实例化后、属性赋值之前阶段的回调方法,属于Bean后置处理器的一种。它在Bean实例化过程中提供了更加细粒度的扩展点,允许开发者在Bean的创建和初始化阶段插入自定义逻辑。

InstantiationAwareBeanPostProcessor接口定义了以下方法:

  1. postProcessBeforeInstantiation: 在Bean实例化之前调用。通过重写该方法,可以返回一个自定义的Bean实例,绕过默认的实例化过程。
  2. postProcessAfterInstantiation: 在Bean实例化后、属性赋值之前调用。可以对已实例化的Bean进行额外的自定义处理,但不能修改实例化后的Bean对象本身。
  3. postProcessProperties: 在Bean的属性赋值之前调用,可以对属性进行额外的处理。可以返回一个自定义的属性对象,或者修改现有的属性对象。


DestructionAwareBeanPostProcessor

DestructionAwareBeanPostProcessor是Spring框架中的一个扩展接口,它继承了BeanPostProcessor接口,并添加了在Bean销毁阶段的回调方法。

DestructionAwareBeanPostProcessor接口定义了以下两个方法:

  1. postProcessBeforeDestruction: 在Bean销毁之前调用。在此方法中,可以对Bean进行进一步的自定义处理或清理操作。
  2. requiresDestruction: 定义了一个方法,标识是否需要在Bean销毁时调用postProcessBeforeDestruction方法。返回true表示需要,返回false表示不需要。

DestructionAwareBeanPostProcessor的主要作用是允许在Bean销毁阶段插入自定义的逻辑。通过实现该接口的方法,可以在Bean销毁之前对Bean进行一些清理操作,例如释放资源、关闭连接、取消注册等。



发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言