Spring 源码之Spring Bean 的创建过程方法之一

到目前为止,我们知道 Spring 创建 Bean 对象有5中方法,分别是:

  • 使用 FactoryBeangetObject 方法创建
  • 使用 BeanPostProcessor 的子接口 InstantiationAwareBeanPostProcessorpostProcessBeforeInstantiation 方法创建
  • 设置 BeanDefinitionSupplier 属性进行创建
  • 设置 BeanDefinitionfactory-method 进行创建
  • 使用全过程: getBean-->doGetBean-->createBean-->doCreateBean 反射进行创建

前面4中已经介绍,接下来介绍第5种,我们知道如果使用反射创建,那么必然要知道使用构造函数进行实例化,因为使用构造函数能够将带有参数的设置进去。

SmartInstantiationAwareBeanPostProcessor 接口

在前面讲过 InstantiationAwareBeanPostProcessor 是用来提前实例化对象的,而 SmartInstantiationAwareBeanPostProcessorInstantiationAwareBeanPostProcessor 的子接口,他是用来干啥呢?

createBeanInstance 方法中的源码:

// 省略代码....
// 明确构造器从BeanPostProcessor中,对应的是 AutowiredAnnotationBeanPostProcessor
// 他是 SmartInstantiationAwareBeanPostProcessor 的子类,使用determineCandidateConstructors进行
// 解析构造函数
Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 省略代码....

点进去:

protected Constructor[] determineConstructorsFromBeanPostProcessors(@Nullable Class beanClass, String beanName)
throws BeansException {

if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
// 决定候选的构造函数
Constructor[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
}
return null;
}

可以看到这个接口是用来解析 BeanClass 的构造函数的, SmartInstantiationAwareBeanPostProcessor 的实现类 AutowiredAnnotationBeanPostProcessor ,这个类是用来解析确定合适的构造函数,重点解析了 @Autowired 注解,并且还解析了 @Value 注解和 @Lookup 注解。

当解析出来构造函数之后,那么就调用 autowireConstructor 方法进行实例化,解析时会new一个构造器解析器 ConstructorResolver ,在解析 factoryMehod 时也是使用的这个类使用的是 instantiateUsingFactoryMethod 这个方法,并且解析 factoryMethod 更加复杂,需要判断是否是静态的工厂创建还是实例工厂创建,而自动装配的构造解析相对来说简单一些,使用 autowireConstructor 方法进行解析。

最终解析出构造方法和构造参数之后进行实例化:

// 使用合适的构造方法和构造参数进行实例化
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));

实例化:

private Object instantiate(
String beanName, RootBeanDefinition mbd, Constructor constructorToUse, Object[] argsToUse) {

try {
// 获取实例化策略,一般使用 CglibSubClassingInstantiationStrategy
InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy();
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedAction) () ->
strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse),
this.beanFactory.getAccessControlContext());
}
else {
// 开始实例化
return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
final Constructor ctor, Object... args) {
if (!bd.hasMethodOverrides()) {
if (System.getSecurityManager() != null) {
// use own privileged to change accessibility (when security is on)
AccessController.doPrivileged((PrivilegedAction) () -> {
ReflectionUtils.makeAccessible(ctor);
return null;
});
}
// 实例化类,反射调用
return BeanUtils.instantiateClass(ctor, args);
}
else {
// 如果方法被覆盖,lookup-method 和 replace-method
return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
}
}

如果前面的解析都没有到 Bean ,那么就会使用无参构造函数进行解析:

// 省略代码....
// Preferred constructors for default construction?
// 首选的构造器为默认的创建方式,使用了@Primary注解的为首选的创建对象方式
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}

// No special handling: simply use no-arg constructor.
// 调用无参构造函数实例化对象
return instantiateBean(beanName, mbd);

实例化 Bean

protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(
(PrivilegedAction) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
// 实例化对象,使用反射进行创建
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
// 创建一个Bean的包装器
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
// 初始化Bean的包装器
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}

这里可以看到前面使用 factoryMethodautowireConstructor 解析构造函数进行实例化还是使用无参构造函数进行实例化都是将 Bean 进行了包装,那这个包装有啥作用呢?

BeanWrapper的作用

我们先来看下前面的方法是怎么创建 BeanWrapper 的:

factory-method 解析, ConstructorResolver#instantiateUsingFactoryMethod 方法:

public BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
// 创建一个Bean的包装器
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
// factoryBean
Object factoryBean;
// factory 工厂类
Class factoryClass;
// 标识是否是静态的工厂
boolean isStatic;
// 省略代码....
}

SmartInstantiationAwareBeanPostProcessor 子类 AutowiredAnnotationBeanPostProcessor 解析出构造函数,然后使用 ConstructorResolver#autowireConstructor 执行:

public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor[] chosenCtors, @Nullable Object[] explicitArgs) {
// 创建一个包装器
BeanWrapperImpl bw = new BeanWrapperImpl();
// 初始化包装器
this.beanFactory.initBeanWrapper(bw);
// 构造函数
Constructor constructorToUse = null;
// 构造参数
ArgumentsHolder argsHolderToUse = null;
// 需要使用的构造参数
Object[] argsToUse = null;
// 明确的构造参数不为空,则赋值给将要执行实例化的构造参数
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
// 省略代码....
}

最终都是会进行转换服务 ConversionServicePropertyEditorRegistry 的注册,一个是用来进行属性类型转换的,一个是用来属性值解析的:

protected void initBeanWrapper(BeanWrapper bw) {
// 获取转换服务放到bean的包装器中
bw.setConversionService(getConversionService());
// 注册定制的属性编辑器
registerCustomEditors(bw);
}

在前面的文章中,介绍了这两个如何使用,而且还自定义了属性编辑器和类型转换,需要的小伙伴可以去看看:

Spring 源码(5)BeanFactory使用的准备及自定义属性值解析器 - 玲丶蹊 - 博客园 和 Spring 源码(9)Spring Bean的创建过程的前期准备 - 玲丶蹊 - 博客园

到这里Bean的实例化就完成了,接着往下看源码:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
// 从缓存中获取FactoryBean的Bean对象
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 实例化对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 从包装器中获取Bean对象
Object bean = instanceWrapper.getWrappedInstance();
// 从包装器中获取Bean类型
Class beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}

// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 合并Bean
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
}

点进去:

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
// 执行合并BeanDefinition
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}

可以看到这里出现了一个接口 MergedBeanDefinitionPostProcessor ,这个接口也是 BeanPostProcessor 的子接口,那他到底是干啥用的呢?

MergedBeanDefinitionPostProcessor 接口

点击发现这个接口的实现类全是跟注解相关的,而最重要的是 CommonAnnotationBeanPostProcessor 实现类,在构造函数中设置了两个注解: @PostConstruct@PreDestroy ,一个是在初始化完之后调用,一个是容器销毁时调用。

你可能感兴趣的:(Spring 源码之Spring Bean 的创建过程方法之一)