spring中bean创建过程中的扩展点

Posted 我爱看明朝

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring中bean创建过程中的扩展点相关的知识,希望对你有一定的参考价值。

spring中bean创建过程中的扩展点

spring中bean的生命周期

Spring中的bean在创建过程中大概分为一下几个步骤:

实例化 --> 填充属性 --> 执行aware接口 --> 初始化 --> 可用状态 --> 销毁

1.实例化就是调用类的构造器进行对象创建的过程,比如:new Object();就实例化了一个Obejct对象;

2.填充属性是指注入bean的依赖或者给属性赋值;

3.Aware接口是Spring中的“觉醒”接口,是Spring容器通过回调向bean注入相关对象的接口;

4.初始化是指完成bean的创建和依赖注入后进行的一个回调,可以利用这个回调进行一些自定义的工作,实现初始化的方式有三种,分别是实现InitializingBean接口、使用@PostConstruct注解和xml中通过init-method属性指定初始化方法;

5.可用状态是指bean已经准备就绪、可以被应用程序使用了,此时bean会一直存在于Spring容器中;

6.销毁是指这个bean从Spring容器中消除,这个操作往往伴随着Spring容器的销毁。实现销毁方法的方式有3中,分别为实现DisposableBean接口、使用@PreDestroy注解和xml中通过destroy-method属性指定。

扩展点

spring提供给了分别在实例化、初始化前后提供了扩展点(EP : extension point )

实例化: new出bean
初始化: 设置bean中的依赖、属性

EP1 --> 实例化 --> EP2 --> 填充属性 —> 执行aware接口 --> EP3 --> 初始化 --> EP4 --> 可用状态 --> 销毁

public interface BeanPostProcessor { 

    // 初始化前的扩展点 EP3
    @Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

    // 初始化后的扩展点 EP4
    @Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}


}

public abstract class InstantiationAwareBeanPostProcessorAdapter implements SmartInstantiationAwareBeanPostProcessor {

    // 实例化前的扩展点   EP1
    @Override
	@Nullable
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

    // 实例化后的扩展点 EP2
	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}

    // 初始化前的扩展点 EP3
    @Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

    // 初始化后的扩展点 EP4
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
}


InstantiationAwareBeanPostProcessorAdapter顶层也是BeanPostProcessor,这个类可以对初始化。实例化前后进行扩展,直接实现BeanPostProcessor接口只能在初始化前后扩展,

源码分析:Spring中的bean在创建过程中大概分为一下几个步骤

EP1 -->  实例化 --> EP2 --> 填充属性 ---> EP3 --->  初始化 ---> EP4 --> 使用 ---> 销毁

通过InstantiationAwareBeanPostProcessorAdapter中的方法,我们定位到,四个EP皆在AbstractAutowireCapableBeanFactory类中有调用。

AbstractAutowireCapableBeanFactory

我们先来看下doc的描述,AbstractAutowireCapableBeanFactory这个抽象类是干啥的。

/**
 * Abstract bean factory superclass that implements default bean creation,
 * with the full capabilities specified by the {@link RootBeanDefinition} class.
 * Implements the {@link org.springframework.beans.factory.config.AutowireCapableBeanFactory}
 * interface in addition to AbstractBeanFactory's {@link #createBean} method.
 *
 * <p>Provides bean creation (with constructor resolution), property population,
 * wiring (including autowiring), and initialization. Handles runtime bean
 * references, resolves managed collections, calls initialization methods, etc.
 * Supports autowiring constructors, properties by name, and properties by type.
 *
 * <p>The main template method to be implemented by subclasses is
 * {@link #resolveDependency(DependencyDescriptor, String, Set, TypeConverter)},
 * used for autowiring by type. In case of a factory which is capable of searching
 * its bean definitions, matching beans will typically be implemented through such
 * a search. For other factory styles, simplified matching algorithms can be implemented.
 *
 * <p>Note that this class does <i>not</i> assume or implement bean definition
 * registry capabilities. See {@link DefaultListableBeanFactory} for an implementation
 * of the {@link org.springframework.beans.factory.ListableBeanFactory} and
 * {@link BeanDefinitionRegistry} interfaces, which represent the API and SPI
 * view of such a factory, respectively.
 /**

/**
* 大致翻译一下:
*
* 这个类实现了AutowireCapableBeanFactory接口,可以用来创建bean.
*
* 主要功能: 创建bean,实例化,属性填充(包含@autowire注解的属性),初始化,调用初始化方法,
*  			以及 执行aware接口,填充beanName......
*
* 通俗说 EP1 -->  实例化 --> EP2 --> 填充属性 ---> EP3 --->  初始化 ---> EP4 都在这个类里完成。
**/

AbstractAutowireCapableBeanFactory的顶层接口是BeanFactory

BeanFactory AutowireCapableBeanFactory AbstractAutowireCapableBeanFactory

AbstractAutowireCapableBeanFactory在创建bean时主要做了一下工作:
createBeanInstance: 实例化
populateBean: 填充属性
initalizaBean: 初始化类

createBean

//创建bean方法
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException  {
	//EP1扩展点
	Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
	//EP2以及填充属性,EP3,EP4扩展点
	Object beanInstance = doCreateBean(beanName, mbdToUse, args);
}

resolveBeforeInstantiation

createBean
resolveBeforeInstantiation
applyBeanPostProcessorsBeforeInstantiation
postProcessBeforeInstantiation
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
	bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
}

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
	Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
}

doCreateBean

以上是关于spring中bean创建过程中的扩展点的主要内容,如果未能解决你的问题,请参考以下文章

小白面试题:Spring中Bean的初始化过程

Spring 源码 Spring Bean的创建过程的前期准备

0001 - Spring 框架和 Tomcat 容器扩展接口揭秘

spring生命周期

Spring源码系列 — BeanDefinition扩展点

Spring IOC 容器源码分析 - 填充属性到 bean 原始对象