当前位置 : 主页 > 编程语言 > 其它开发 >

Spring 源码(14)Spring Bean 的创建过程(5)

来源:互联网 收集:自由互联 发布时间:2022-05-14
到目前为止,我们知道 Spring 创建 Bean 对象有5中方法,分别是: 使用 FactoryBean 的 getObject 方法创建 使用 BeanPostProcessor 的子接口 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 方

到目前为止,我们知道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<Object>) () ->
                                           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<Object>) () -> {
        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<Object>) () -> 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);
}

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

https://www.cnblogs.com/redwinter/p/16167214.html 和 https://www.cnblogs.com/redwinter/p/16241328.html

到这里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 ,一个是在初始化完之后调用,一个是容器销毁时调用。

未完待续.....

网友评论