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源码分析之循环依赖

目录
相关文章
|
1月前
|
XML 安全 Java
|
2月前
|
监控 Java 应用服务中间件
Spring Boot整合Tomcat底层源码分析
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置和起步依赖等特性,大大简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是其与Tomcat的整合。
62 1
|
9天前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
8天前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
8天前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
14天前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
51 6
|
15天前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
79 3
|
2月前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
29天前
|
安全 Java 开发者
Spring容器中的bean是线程安全的吗?
Spring容器中的bean默认为单例模式,多线程环境下若操作共享成员变量,易引发线程安全问题。Spring未对单例bean做线程安全处理,需开发者自行解决。通常,Spring bean(如Controller、Service、Dao)无状态变化,故多为线程安全。若涉及线程安全问题,可通过编码或设置bean作用域为prototype解决。
34 1
|
2月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
40 1