0

Spring 源码(14)Spring Bean 的创建过程(5) - 玲丶蹊

 2 years ago
source link: https://www.cnblogs.com/redwinter/p/16268667.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

到目前为止,我们知道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.htmlhttps://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 ,一个是在初始化完之后调用,一个是容器销毁时调用。

未完待续.....


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK