Spring源码分析之Bean的创建过程详解(二)

简介: Spring源码分析之Bean的创建过程详解

createBeanInstance

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){
  // 获取beanClass
  Class<?> beanClass = resolveBeanClass(mbd, beanName);
  // 使用AutowiredAnnotationBeanPostProcessor进行构造器推断,找到所有的有参构造器
  Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
  if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
    // 实例化bean,并根据参数自动装配
    return autowireConstructor(beanName, mbd, ctors, args);
  }
  // 调用无参的构造方法实例化
  return instantiateBean(beanName, mbd);
}

determineConstructorsFromBeanPostProcessors

protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
      throws BeansException {
  if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
        // 只有AutowiredAnnotationBeanPostProcessor进行了实现,其他的都返回null
        SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
        // 确认候选的构造器
        Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
        if (ctors != null) {
          return ctors;
        }
      }
    }
  }
  return null;
}

AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName){
  // 获取到所有的构造方法
  rawCandidates = beanClass.getDeclaredConstructors();
  for (Constructor<?> candidate : rawCandidates) {
    // 是否带有@Autowired注解
    MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
    if (ann != null) {
      // 是否必须
      boolean required = determineRequiredStatus(ann);
      candidates.add(candidate);
    }
    else if (candidate.getParameterCount() == 0) {
      // 无参构造器
      defaultConstructor = candidate;
    }
  }
  // 候选的构造器不为空
  if (!candidates.isEmpty()) {
    // 候选的构造器不为空而requiredConstructor为空表示有@Autowired标识的构造器
    // 但是required=false
    if (requiredConstructor == null) {
      if (defaultConstructor != null) {
        // 将无参构造器也加入到候选构造器集合中
        candidates.add(defaultConstructor);
      }
    }
    // 将集合中的构造器转化为数组
    candidateConstructors = candidates.toArray(new Constructor<?>[0]);
  }
  // 候选的构造器为空,但有一个有参构造器,则使用有参构造器作为候选的构造器
  else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
    candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
  }
  // 返回候选构造器数组
  return (candidateConstructors.length > 0 ? candidateConstructors : null);
}

autowireConstructor 实例化并自动装配,摘取代码片段

protected BeanWrapper autowireConstructor(
      String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
  return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
      @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
  for (Constructor<?> candidate : candidates) {
    // 获取参数的类型
    Class<?>[] paramTypes = candidate.getParameterTypes();
    // 获取依赖的bean
    argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames..);
    // 调用instantiate方法进行实例化bean
    bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
  }
}

以上便是bean的实例化过程

applyMergedBeanDefinitionPostProcessors

第三次主要是将标识了需要自动装配注解的属性或方法解析出来,包含的注解主要有 @Resource @Autowired @Value @Inject @PostConstruct @PreDestroy

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
  for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof MergedBeanDefinitionPostProcessor) {
      // CommonAnnotationBeanPostProcessor解析@PostConstruct @PreDestroy @Resource
      // AutowiredAnnotationBeanPostProcessor 解析@Autowired @Value @Inject
      MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
      bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
    }
  }
}

CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
  // 父类为InitDestroyAnnotationBeanPostProcessor
  // 寻找@PostConstruct @PreDestroy注解的方法
  // 用于bean的生命周期中初始化前的处理逻辑
  super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
  // 寻找@Resource注解标识的属性或方法元数据
  // 将这些元数据保存到缓存中,用于在属性装配阶段使用
  InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
  // 检查是否有重复的元数据,去重处理,如一个属性上既有@Autowired注解,又有@Resource注解
  // 只使用一种方式进行注入,由于@Resource先进行解析,所以会选择@Resource的方式
  metadata.checkConfigMembers(beanDefinition);
}

InitDestroyAnnotationBeanPostProcessor#postProcessMergedBeanDefinition

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
  // 寻找PostConstruct @PreDestroy注解的方法
  LifecycleMetadata metadata = findLifecycleMetadata(beanType);
  // 去重处理
  metadata.checkConfigMembers(beanDefinition);
}

所有的后置处理器的过程是相似的,这里取CommonAnnotationBeanPostProcessor进行分析

我们先来看看寻找元数据的过程

private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) {
  String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
  // 从缓存中获取
  // 调用postProcessMergedBeanDefinition方法时将元数据解析放入缓存
  // 调用postProcessProperties方法时将元数据取出
  InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
  if (InjectionMetadata.needsRefresh(metadata, clazz)) {
    synchronized (this.injectionMetadataCache) {
      metadata = this.injectionMetadataCache.get(cacheKey);
      if (InjectionMetadata.needsRefresh(metadata, clazz)) {
        if (metadata != null) {
          metadata.clear(pvs);
        }
        // 创建元数据,寻找@Resouce标识的属性或方法
        metadata = buildResourceMetadata(clazz);
        this.injectionMetadataCache.put(cacheKey, metadata);
      }
    }
  }
  return metadata;
}

buildResourceMetadata

private InjectionMetadata buildResourceMetadata(final Class<?> clazz){
  // 判断是否为候选的class,不是则返回默认的空元数据
  // resourceAnnotationTypes为Annotation集合,里面包含了@Resource @EJB @WebServiceRef
  // 我们一般常用的只是@Resource
  if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {
    return InjectionMetadata.EMPTY;
  }
  do {
    // 循环所有的属性,判断属性是否存在WebServiceRef、EJB、Resource注解,有则构建元数据
    // doWithLocalFields中就是将targetClass的所有field取出进行循环
    ReflectionUtils.doWithLocalFields(targetClass, field -> {
      if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
        currElements.add(new WebServiceRefElement(field, field, null));
      }
      else if (ejbClass != null && field.isAnnotationPresent(ejbClass)) {
        currElements.add(new EjbRefElement(field, field, null));
      }
      // 是否存在@Resource注解
      else if (field.isAnnotationPresent(Resource.class)) {
        if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
          currElements.add(new ResourceElement(field, field, null));
        }
      }
    }); 
    // 与上一步相似,判断方法上是否存在这些注解
    ReflectionUtils.doWithLocalMethods(targetClass, method -> {
      //......省略
    });
    // 获取父类
    targetClass = targetClass.getSuperclass();
  }
  // 父类不是Object则继续循环父类中的属性和方法
  while (targetClass != null && targetClass != Object.class);
  // 将构建好的元数据封装到InjectionMetadata中返回
  return InjectionMetadata.forElements(elements, clazz);
}

现在我们再来看看去重处理的过程

public void checkConfigMembers(RootBeanDefinition beanDefinition) {
    Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
  for (InjectedElement element : this.injectedElements) {
    Member member = element.getMember();
    // 检查该beanDefinition的externallyManagedConfigMembers集合中是否已经包含该成员(属性或者方法)
    if (!beanDefinition.isExternallyManagedConfigMember(member)) {
      // 不包含则将该成员注册
      beanDefinition.registerExternallyManagedConfigMember(member);
      // 加入到已检查的集合
      checkedElements.add(element);
    }
  }
  this.checkedElements = checkedElements;
}

由于第四次,用于获取早期对象时的处理的调用,在Spring的内置处理器中也没有相应的实现,跳过

这一步和第一步一样,在AOP时将会用到,我们放到下章分析

紧接着就是填充属性的步骤了

populateBean

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
  // 在这里可进行中止填充属性操作,实现InstantiationAwareBeanPostProcessor接口
  // 并postProcessAfterInstantiation返回false,则直接返回,不会再往下执行
  // Spring内中的后置处理器皆返回的true
  if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
        if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
          return;
        }
      }
    }
  }
  // 获得自动装配的类型,默认为0,
  // 这里只有xml配置,ImportBeanDefinitionRegistrar,BeanFactoryPostProcessor可进行改变
  // Spring整合Mybatis中,将Mapper的自动装配类型改成了BY_TYPE,
  // 于是在Mapper得以在这里被填充SqlSessionTemplate,SqlSessionFactory属性
  int resolvedAutowireMode = mbd.getResolvedAutowireMode();
  if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
      autowireByName(beanName, mbd, bw, newPvs);
    }
    if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
      // 获取到依赖的bean并放到newPvs中
      autowireByType(beanName, mbd, bw, newPvs);
    }
    // 将新的属性列表赋给旧的引用
    pvs = newPvs;
  }
}

autowireByName 和 autowireByType差不多,autowireByType更为复杂一些,这里只分析autowireByType的处理过程

protected void autowireByType(
      String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
  // 查询非简单(Java内置 基本类型,String,Date等)的属性
  String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
  // 循环所有属性名
  for (String propertyName : propertyNames) {
    // 获取方法参数
    MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
    // 构建一个依赖描述符
    DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
    // 获取依赖的bean 
    // resolveDependency方法中调用了doResolveDependency,该方法我们在下一步的后置处理器调用中分析
    Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
    // 将bean放置到属性集合中
    if (autowiredArgument != null) {
      pvs.add(propertyName, autowiredArgument);
    }
  }
}

现在,回到填充属性的过程

目录
相关文章
|
23天前
|
缓存 Java Spring
Spring 框架中 Bean 的生命周期
Spring 框架中 Bean 的生命周期
32 1
|
1月前
|
XML Java 开发者
Spring Boot中的bean注入方式和原理
Spring Boot中的bean注入方式和原理
57 0
|
1月前
|
XML 缓存 Java
Spring源码之 Bean 的循环依赖
循环依赖是 Spring 中经典问题之一,那么到底什么是循环依赖?简单说就是对象之间相互引用, 如下图所示: 代码层面上很好理解,在 bean 创建过程中 class A 和 class B 又经历了怎样的过程呢? 可以看出形成了一个闭环,如果想解决这个问题,那么在属性填充时要保证不二次创建 A对象 的步骤,也就是必须保证从容器中能够直接获取到 B。 一、复现循环依赖问题 Spring 中默认允许循环依赖的存在,但在 Spring Boot 2.6.x 版本开始默认禁用了循环依赖 1. 基于xml复现循环依赖 定义实体 Bean java复制代码public class A {
|
8天前
|
Java 数据库连接 开发者
浅谈Spring的Bean生命周期
浅谈Spring的Bean生命周期
17 1
|
12天前
|
XML Java 数据格式
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
19 0
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
|
23天前
|
XML Java 程序员
作为Java程序员还不知道Spring中Bean创建过程和作用?
作为Java程序员还不知道Spring中Bean创建过程和作用?
14 0
|
27天前
|
XML 缓存 Java
天天用 Spring,bean 实例化原理你懂吗
天天用 Spring,bean 实例化原理你懂吗
17 0
|
1月前
|
Java Spring
Spring5深入浅出篇:bean的生命周期
Spring5深入浅出篇:bean的生命周期
|
1月前
|
XML Java 数据格式
Spring 的奇幻起源:从 IoC 容器到 Bean 的魔法世界 (下)
Spring 的奇幻起源:从 IoC 容器到 Bean 的魔法世界
|
1月前
|
XML Java 数据格式
Spring 的奇幻起源:从 IoC 容器到 Bean 的魔法世界 (上)
Spring 的奇幻起源:从 IoC 容器到 Bean 的魔法世界 (上)