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

虚幻大学 xuhss 109℃ 0评论

? 优质资源分享 ?

学习路线指引(点击解锁) 知识定位 人群定位
? Python实战微信订餐小程序 ? 进阶级 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
?Python量化交易实战? 入门级 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

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

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

https://blog.csdn.net/redwinter/p/16167214.htmlhttps://blog.csdn.net/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 ,一个是在初始化完之后调用,一个是容器销毁时调用。

未完待续.....

转载请注明:xuhss » Spring 源码(14)Spring Bean 的创建过程(5)

喜欢 (0)

您必须 登录 才能发表评论!