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

导读:本篇文章讲解 Spring 源码(14)Spring Bean 的创建过程(5),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

到目前为止,我们知道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 接口

点击发现这个接口的实现类全是跟注解相关的,包括AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessorInitDestroyAnnotationBeanPostProcessor 实现类,CommonAnnotationBeanPostProcessor在构造函数中设置了两个注解:@PostConstruct@PreDestroy ,一个是在初始化完之后调用,一个是容器销毁时调用。CommonAnnotationBeanPostProcessor这个类的父类为InitDestroyAnnotationBeanPostProcessor`,用于处理初始化和销毁方法的。

CommonAnnotationBeanPostProcessor 的构造器:

public CommonAnnotationBeanPostProcessor() {
		setOrder(Ordered.LOWEST_PRECEDENCE - 3);
		// 初始化PostConstruct PreDestroy注解
		// 调用父类的方法进行设置
		setInitAnnotationType(PostConstruct.class);
		setDestroyAnnotationType(PreDestroy.class);
		ignoreResourceType("javax.xml.ws.WebServiceContext");
	}

CommonAnnotationBeanPostProcessor 合并方法:

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		// 调用父类
		super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
		InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}

点击postProcessMergedBeanDefinition方法发现调用了父类的这个方法,然后执行了一个叫查找生命周期元数据的方法findLifecycleMetadata

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		LifecycleMetadata metadata = findLifecycleMetadata(beanType);
		metadata.checkConfigMembers(beanDefinition);
	}

查找生命周期元数据:

private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
		if (this.lifecycleMetadataCache == null) {
			// Happens after deserialization, during destruction...
			return buildLifecycleMetadata(clazz);
		}
		// Quick check on the concurrent map first, with minimal locking.
		// 查询缓存
		LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
		if (metadata == null) {
			synchronized (this.lifecycleMetadataCache) {
				// 再次查询
				metadata = this.lifecycleMetadataCache.get(clazz);
				if (metadata == null) {
					// 没有查询到就去构建生命周期的元数据
					metadata = buildLifecycleMetadata(clazz);
					this.lifecycleMetadataCache.put(clazz, metadata);
				}
				return metadata;
			}
		}
		return metadata;
	}

构建生命周期元数据:

private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
  // 这里的initAnnotationType 就是子类set进去的@PostConstruct
  // destroyAnnotationType 就是子类set进去的@PreDestroy
  if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
    return this.emptyLifecycleMetadata;
  }
  // 存放初始化方法
  List<LifecycleElement> initMethods = new ArrayList<>();
  // 存放销毁方法
  List<LifecycleElement> destroyMethods = new ArrayList<>();
  Class<?> targetClass = clazz;

  do {
    final List<LifecycleElement> currInitMethods = new ArrayList<>();
    final List<LifecycleElement> currDestroyMethods = new ArrayList<>();

    ReflectionUtils.doWithLocalMethods(targetClass, method -> {
      // 如果找到方法上有@PostConstruct注解,这加入到当前初始化方法集合中
      if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
        // 创建一个生命周期元素
        //LifecycleElement element = new LifecycleElement(method);
        currInitMethods.add(new LifecycleElement(method));
      }
      // 如果找到方法上标有@PreDestroy 注解,就加入到当前销毁方法集合中
      if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
        currDestroyMethods.add(new LifecycleElement(method));
      }
    });
    // 赋值到初始化方法集合和销毁方法集合中
    initMethods.addAll(0, currInitMethods);
    destroyMethods.addAll(currDestroyMethods);
    targetClass = targetClass.getSuperclass();
  }
  // 遍历查找
  while (targetClass != null && targetClass != Object.class);
  // 如果没有解析到,那么返回一个空的生命周期元数据,否则创建一个生命周期元素并放入初始化方法和销毁方法的集合
  return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
          new LifecycleMetadata(clazz, initMethods, destroyMethods));
}

最终发现实际上就是在解析我们的Bean的方法上是否标记了@PostConstruct注解和@PreDestroy方法,如果有就加入到生命周期元数据中,并且将解析到的方法放入到BeanDefinitionexternallyManagedInitMethodsexternallyManagedDestroyMethods集合中。

Bean初始化和销毁方法解析和执行流程如下:

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

其实InitDestoryAnnotationBeanPostProcessor 主要是对Bean的做了自定义初始化和销毁方法的解析,以及在后期调用BPP时执行。

自动装配注解的解析

Spring中自动装配的注解一般来说比较常用的有两个,一个@AutowiredSpring提供的,还有个是@ResourceJava的注解,这两个注解都能够完成自动装配,不过在实现时@Autowired注解是由AutowiredAnnotationBeanPostProcessor解析的和执行,而@Resource注解是由CommonAnnotationBeanPostProcessor解析和执行的。

除此之外,AutowiredAnnotationBeanPostProcessor还解析了@Value注解,CommonAnnotationBeanPostProcessor还解析了@EJB@WebServiceRef 不过这个不常用。这些注解的解析跟解析@PostConstruct@PreDestroy一样,这里就不做分析了,不同的是这几个注解可以标在字段和方法上,解析是需要对字段和方法都要解析,其他实现基本原理一致。

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

Spring Bean的实例化基本就解析完了,接下来开始解析循环依赖和Bean的属性填充部分。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/6188.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!