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

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

该第六次调用后置处理器了,这一次主要对属性和方法进行自动装配

// CommonAnnotationBeanPostProcessor 处理@Resouce注解的装配
// AutowiredAnnotationBeanPostProcessor 处理@Autowired @Value @Inject注解的装配
for (BeanPostProcessor bp : getBeanPostProcessors()) {
  if (bp instanceof InstantiationAwareBeanPostProcessor) {
    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    // 处理自动装配,将依赖的属性装配到bean中
    PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
    // ...省略已被废弃的代码...
    pvs = pvsToUse;
  }
}

这一步的逻辑也是差不多,由于AutowiredAnnotationBeanPostProcessor复杂一些,我们取AutowiredAnnotationBeanPostProcessor中的逻辑进行分析

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
  // 取出之前postProcessMergedBeanDefinition时解析好的元数据
  // @Autowired @Value @Inject 标识的属性或方法
  // findAutowiringMetadata这里有没有和第四步中的很像呢~
  InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
  // 进行自动装配
  metadata.inject(bean, beanName, pvs);
  return pvs;
}

findAutowiringMetadata,看看和第四步有多像吧~

private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
    String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
    // 从缓存中取出
    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);
          }
          // 构建元数据,找到@Autowird @Value @Inject 标识的属性或方法进行构建
          metadata = buildAutowiringMetadata(clazz);
          this.injectionMetadataCache.put(cacheKey, metadata);
        }
      }
    }
    return metadata;
  }

自动装配过程

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) {
  // 取出之前去重过的元数据列表
  Collection<InjectedElement> checkedElements = this.checkedElements;
  if (!elementsToIterate.isEmpty()) {
    for (InjectedElement element : elementsToIterate) {
      // 进行属性或方法装配
      element.inject(target, beanName, pvs);
    }
  }
}
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs){
  // 强转成Field
  Field field = (Field) this.member;
  // 创建一个依赖描述符
  DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
  // 获取到依赖的bean
  value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
  if (value != null) {
    ReflectionUtils.makeAccessible(field);
    // 将获取到的依赖bean利用反射装配到属性中
    field.set(bean, value);
  }
}
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
      @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
  // 获取bean
  result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
  return result;
}
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
      @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter){
  // 解析@Value注解
  Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
  if (value != null) {
    return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
  }
  // 根据类型寻找是否有匹配的beanDefinition
  Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
  if (matchingBeans.isEmpty()) {
    // 为空则判断是否必须
    if (isRequired(descriptor)) {
      // 必须则抛出NoSuchBeanDefinitionException异常
      raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
    }
    return null;
  }
  // 如果根据类型匹配出来的候选bean不止一个,则需要确认是哪一个
  if (matchingBeans.size() > 1) {
    // 确认出真正需要依赖的
    // 先判断是否有@Primary注解的
    // 没有再判断是否有实现了Priority注解的,取值最小的
    // 没有最后使用属性名进行匹配
    // 匹配不到则返回null
    autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
    if (autowiredBeanName == null) {
      // 这里进行确认是否必须,必须则抛出异常
      if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
        return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
      }
      else {
        return null;
      }
    }
    instanceCandidate = matchingBeans.get(autowiredBeanName);
  }
  if (instanceCandidate instanceof Class) {
    // 调用getBean方法
    instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
  }
  Object result = instanceCandidate;
  return result;
}

getBean方法

public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) {
  return beanFactory.getBean(beanName);
}

以上就是自动装配的过程,再次回到填充属性的方法,进行小小的收尾

// 如果不是xml byName byType 方式,其他方式pvs皆是空值
if (pvs != null) {
  // 调用set方法赋值
  applyPropertyValues(beanName, mbd, bw, pvs);
}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
  // 使用反射给属性赋值
  bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}

填充属性过程,over~

初始化过程

initializeBean

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd){
  // 如果bean实现了BeanNameAware,BeanClassLoaderAware,BeanFactoryAware接口
  // 则进行回调相应的方法
  invokeAwareMethods(beanName, bean);
  // 第七次 在bean的初始化前进行处理
  // 调用@PostConstruct注解的方法,Aware接口的回调方法
  wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  // 调用初始化方法
  // 如果bean实现了InitializingBean接口,则调用afterPropertiesSet方法
  // 如果bean还实现了自定义的初始化方法,也进行调用
  // 先afterPropertiesSet,再自定义
  invokeInitMethods(beanName, wrappedBean, mbd);
  // 第八次 处理初始化后的bean
  wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

以上为初始化中的大概流程,接下来我们一个个分析

首先是invokeAwareMethods

private void invokeAwareMethods(String beanName, Object bean) {
  // 以下过程一目了然,就不过多分析了
  if (bean instanceof Aware) {
    if (bean instanceof BeanNameAware) {
      ((BeanNameAware) bean).setBeanName(beanName);
    }
    if (bean instanceof BeanClassLoaderAware) {
      ClassLoader bcl = getBeanClassLoader();
      if (bcl != null) {
        ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
      }
    }
    if (bean instanceof BeanFactoryAware) {
      ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
    }
  }
}

applyBeanPostProcessorsBeforeInitialization

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName){
  Object result = existingBean;
  for (BeanPostProcessor processor : getBeanPostProcessors()) {
    // ImportAwareBeanPostProcessor处理ImportAware接口
    // InitDestroyAnnotationBeanPostProcessor处理@PostContrust注解
    // ApplicationContextAwareProcessor处理一系列Aware接口的回调方法
    Object current = processor.postProcessBeforeInitialization(result, beanName);
    if (current == null) {
      return result;
    }
    result = current;
  }
  return result;
}

InitDestroyAnnotationBeanPostProcessor

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  // 取出在第四步解析@PostContrust @PreDestroy得到的元数据
  LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
  // 调用init方法(@PostConstruct标识的)
  metadata.invokeInitMethods(bean, beanName);
  return bean;
}
public void invokeInitMethods(Object target, String beanName) throws Throwable {
  // 只取init的元数据(还有destroy的)
  Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
  if (!initMethodsToIterate.isEmpty()) {
    for (LifecycleElement element : initMethodsToIterate) {
      element.invoke(target);
    }
  }
}
public void invoke(Object target) throws Throwable {
  ReflectionUtils.makeAccessible(this.method);
  // 直接反射调用
  this.method.invoke(target, (Object[]) null);
}

ApplicationContextAwareProcessor的过程和invokeAwareMethods的过程类似,这里就不分析了

invokeInitMethods

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd){
  // 如果实现了InitializingBean接口,调用afterPropertiesSet方法
  boolean isInitializingBean = (bean instanceof InitializingBean);
  if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
    ((InitializingBean) bean).afterPropertiesSet();
  }
  if (mbd != null && bean.getClass() != NullBean.class) {
    // 调用自定义的初始化方法
    String initMethodName = mbd.getInitMethodName();
    if (StringUtils.hasLength(initMethodName) &&
        !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
        !mbd.isExternallyManagedInitMethod(initMethodName)) {
      // 自定义init方法主要在@Bean注解进行声明,取出beanDefinition中的initMethod调用就好了
      invokeCustomInitMethod(beanName, bean, mbd);
    }
  }
}

applyBeanPostProcessorsAfterInitialization

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {
  Object result = existingBean;
  for (BeanPostProcessor processor : getBeanPostProcessors()) {
    // Spring内置后置处理器中,只有ApplicationListenerDetector有处理逻辑
    // ApplicationListenerDetector会将实现了ApplicationListener接口的bean添加到事件监听器列表中
    Object current = processor.postProcessAfterInitialization(result, beanName);
    if (current == null) {
      return result;
    }
    result = current;
  }
  return result;
}
public Object postProcessAfterInitialization(Object bean, String beanName){
  if (bean instanceof ApplicationListener) {
    // 将bean添加到事件监听器列表中
    this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
  }
}

以上,bean初始化完毕!

伴随着bean初始化完毕,bean就算创建完成了,本文也到此结束啦,有问题的小伙伴欢迎在下方留言哟~

下文预告:Spring源码分析之循环依赖

目录
相关文章
|
2月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
18天前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
18天前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
110 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
5天前
|
XML Java 数据格式
spring复习02,xml配置管理bean
详细讲解了Spring框架中基于XML配置文件管理bean的各种方式,包括获取bean、依赖注入、特殊值处理、属性赋值、集合类型处理、p命名空间、bean作用域及生命周期和自动装配。
spring复习02,xml配置管理bean
|
5天前
|
XML Java 数据格式
spring复习03,注解配置管理bean
Spring框架中使用注解配置管理bean的方法,包括常用注解的标识组件、扫描组件、基于注解的自动装配以及使用注解后的注意事项,并提供了一个基于注解自动装配的完整示例。
spring复习03,注解配置管理bean
|
2月前
|
XML Java 数据格式
Spring5入门到实战------5、IOC容器-Bean管理(三)
这篇文章深入探讨了Spring5框架中IOC容器的高级Bean管理,包括FactoryBean的使用、Bean作用域的设置、Bean生命周期的详细解释以及Bean后置处理器的实现和应用。
Spring5入门到实战------5、IOC容器-Bean管理(三)
|
2月前
|
XML Java 数据格式
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
这篇文章是Spring5框架的入门教程,详细讲解了IOC容器中Bean的自动装配机制,包括手动装配、`byName`和`byType`两种自动装配方式,并通过XML配置文件和Java代码示例展示了如何在Spring中实现自动装配。
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
|
2月前
|
XML Java 数据格式
Spring5入门到实战------8、IOC容器-Bean管理注解方式
这篇文章详细介绍了Spring5框架中使用注解进行Bean管理的方法,包括创建Bean的注解、自动装配和属性注入的注解,以及如何用配置类替代XML配置文件实现完全注解开发。
Spring5入门到实战------8、IOC容器-Bean管理注解方式
|
2月前
|
Java Spring
|
2月前
|
前端开发 Java 开发者
下一篇
无影云桌面