Spring IoC源码:createBean(下)

简介: Spring IoC源码:createBean(下)

文章目录

Spring源码系列:

前言

正文

方法1:initializeBean

方法2:invokeAwareMethods

方法3:applyBeanPostProcessorsBeforeInitialization

方法4:invokeInitMethods

方法5:invokeCustomInitMethod

方法6:applyBeanPostProcessorsAfterInitialization

方法7:registerDisposableBeanIfNecessary

方法8:requiresDestruction

方法9:hasDestroyMethod

方法10:hasApplicableProcessors

总结

Spring源码系列:

Spring IOC源码:简单易懂的Spring IOC 思路介绍

Spring IOC源码:核心流程介绍

Spring IOC源码:ApplicationContext刷新前准备工作

Spring IOC源码:obtainFreshBeanFactory 详解(上)

Spring IOC源码:obtainFreshBeanFactory 详解(中)

Spring IOC源码:obtainFreshBeanFactory 详解(下)

Spring IOC源码:<context:component-scan>源码详解

Spring IOC源码:invokeBeanFactoryPostProcessors 后置处理器详解

Spring IOC源码:registerBeanPostProcessors 详解

Spring IOC源码:实例化前的准备工作

Spring IOC源码:finishBeanFactoryInitialization详解

Spring IoC源码:getBean 详解

Spring IoC源码:createBean( 上)

Spring IoC源码:createBean( 中)

Spring IoC源码:createBean( 下)

Spring IoC源码:finishRefresh 完成刷新详解

前言

上篇文章讲解了实例化后,初始化属性注入过程中属性值的解析过程及其注入过程,本篇继续讲解doCreateBean流程中属性注入后的其它流程,即对bean实例进行初始化。

正文

populateBean方法执行完成后,开始初始化bean。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {
    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
    //如果是单例并且是FactoryBean则尝试移除
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
      //创建Bean实例,通过策略进行创建,如果选择有参构造或无参构造
      instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    //获取当前实例对象
    final Object bean = instanceWrapper.getWrappedInstance();
    //当前实例的Calss对象
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
      //设置当前bean定义信息的目标类型
      mbd.resolvedTargetType = beanType;
    }
    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
        try {
          //执行MergedBeanDefinitionPostProcessor类型后置处理器的postProcessMergedBeanDefinition方法,
          //如@Autowire注解,就是通过该后置处理器进行解析
          applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
        }
        catch (Throwable ex) {
          throw new BeanCreationException(mbd.getResourceDescription(), beanName,
              "Post-processing of merged bean definition failed", ex);
        }
        mbd.postProcessed = true;
      }
    }
    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    //如果是单例,允许循环依赖,并且beanName正在创建中
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
        isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
      if (logger.isTraceEnabled()) {
        logger.trace("Eagerly caching bean '" + beanName +
            "' to allow for resolving potential circular references");
      }
      //包装成FactoryObject对象,并添加到三级缓存中
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }
    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
      //初始化过程,进行属性注入。该过程递归创建其依赖的属性。如果A中有B,B中有C,则创建B跟C。
      populateBean(beanName, mbd, instanceWrapper);
      //该过程执行后置处理器的before方法,bean的init方法,后置处理器的after方法,可能会生成新的bean对象
      exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    catch (Throwable ex) {
      if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
        throw (BeanCreationException) ex;
      }
      else {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
      }
    }
    if (earlySingletonExposure) {
      //从缓存中获取,因为上面我们将其添加到三级缓存中,从三级缓存中获取会调用FactoryObject对象的getObject方法,可能会触发AOP代理。返回代理对象
      Object earlySingletonReference = getSingleton(beanName, false);
      if (earlySingletonReference != null) {
        //如果bean对象还是原来的,则将三级缓存中获取的对象赋值过去
        if (exposedObject == bean) {
          exposedObject = earlySingletonReference;
        }
        //如果exposedObject在initializeBean方法中被增强 && 不允许在循环引用的情况下使用注入原始bean实例
        else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
          //  获取依赖当前beanName的所有bean名称
          String[] dependentBeans = getDependentBeans(beanName);
          Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
          //尝试移除这些bean的实例,因为这些bean依赖的bean已经被增强了,他们依赖的bean相当于脏数据
          for (String dependentBean : dependentBeans) {
            if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
              actualDependentBeans.add(dependentBean);
            }
          }
          if (!actualDependentBeans.isEmpty()) {
            throw new BeanCurrentlyInCreationException(beanName,
                "Bean with name '" + beanName + "' has been injected into other beans [" +
                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                "] in its raw version as part of a circular reference, but has eventually been " +
                "wrapped. This means that said other beans do not use the final version of the " +
                "bean. This is often the result of over-eager type matching - consider using " +
                "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
          }
        }
      }
    }
    // Register bean as disposable.
    try {
      //注册用于销毁的bean,执行销毁操作的有三种:自定义destroy方法、DisposableBean接口、DestructionAwareBeanPostProcessor
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
      throw new BeanCreationException(
          mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }
    return exposedObject;
  }

initializeBean(beanName, exposedObject, mbd),见方法1详解

registerDisposableBeanIfNecessary(beanName, bean, mbd),见方法7详解

方法1:initializeBean

  protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
        invokeAwareMethods(beanName, bean);
        return null;
      }, getAccessControlContext());
    }
    else {
      //对bean的aware属性进行填充
      invokeAwareMethods(beanName, bean);
    }
    Object wrappedBean = bean;
    //执行BeanPostProcessors的postProcessBeforeInitialization方法,可能会返回新的对象值
    if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
    try {
      //调用初始化方法
      invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
      throw new BeanCreationException(
          (mbd != null ? mbd.getResourceDescription() : null),
          beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
      //执行BeanPostProcessors的postProcessAfterInitialization方法,AOP代理就是在这个步骤进行处理的
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
  }

invokeAwareMethods(beanName, bean),见方法2详解


applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName),见方法3详解


invokeInitMethods(beanName, wrappedBean, mbd),见方法4详解


applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName),见方法6详解

方法2:invokeAwareMethods

  private void invokeAwareMethods(final String beanName, final Object bean) {
    //如果实现了Aware接口,根据实现不同接口,对属性进行填充
    if (bean instanceof Aware) {
      //填充beanName值
      if (bean instanceof BeanNameAware) {
        ((BeanNameAware) bean).setBeanName(beanName);
      }
      if (bean instanceof BeanClassLoaderAware) {
        //填充ClassLoader 
        ClassLoader bcl = getBeanClassLoader();
        if (bcl != null) {
          ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
        }
      }
      if (bean instanceof BeanFactoryAware) {
        //填充当前beanFactory工厂
        ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
    }
  }

方法3:applyBeanPostProcessorsBeforeInitialization

  public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
      throws BeansException {
    Object result = existingBean;
    //执行BeanPostProcessors的postProcessBeforeInitialization方法,可能会返回新的对象值。
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
      Object current = processor.postProcessBeforeInitialization(result, beanName);
      if (current == null) {
        return result;
      }
      result = current;
    }
    return result;
  }

方法4:invokeInitMethods

  protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
      throws Throwable {
    //判断是否实现了InitializingBean接口,如果是则调用afterPropertiesSet方法
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
      if (logger.isTraceEnabled()) {
        logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
      }
      if (System.getSecurityManager() != null) {
        try {
          AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
            ((InitializingBean) bean).afterPropertiesSet();
            return null;
          }, getAccessControlContext());
        }
        catch (PrivilegedActionException pae) {
          throw pae.getException();
        }
      }
      else {
        ((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)) {
        invokeCustomInitMethod(beanName, bean, mbd);
      }
    }
  }

invokeCustomInitMethod(beanName, bean, mbd),见方法5详解

方法5:invokeCustomInitMethod

  protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
      throws Throwable {
    //获取配置的init方法名称
    String initMethodName = mbd.getInitMethodName();
    Assert.state(initMethodName != null, "No init method set");
    //获取初始化方法
    Method initMethod = (mbd.isNonPublicAccessAllowed() ?
        BeanUtils.findMethod(bean.getClass(), initMethodName) :
        ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
    //如果找不到则判断是否强制执行,强制则抛异常,非强制则警告提示
    if (initMethod == null) {
      if (mbd.isEnforceInitMethod()) {
        throw new BeanDefinitionValidationException("Could not find an init method named '" +
            initMethodName + "' on bean with name '" + beanName + "'");
      }
      else {
        if (logger.isTraceEnabled()) {
          logger.trace("No default init method named '" + initMethodName +
              "' found on bean with name '" + beanName + "'");
        }
        // Ignore non-existent default lifecycle methods.
        return;
      }
    }
    if (logger.isTraceEnabled()) {
      logger.trace("Invoking init method  '" + initMethodName + "' on bean with name '" + beanName + "'");
    }
    Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
    if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
        ReflectionUtils.makeAccessible(methodToInvoke);
        return null;
      });
      try {
        AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
            methodToInvoke.invoke(bean), getAccessControlContext());
      }
      catch (PrivilegedActionException pae) {
        InvocationTargetException ex = (InvocationTargetException) pae.getException();
        throw ex.getTargetException();
      }
    }
    else {
      try {
      //设置权限
        ReflectionUtils.makeAccessible(methodToInvoke);
        //执行
        methodToInvoke.invoke(bean);
      }
      catch (InvocationTargetException ex) {
        throw ex.getTargetException();
      }
    }
  }


方法6:applyBeanPostProcessorsAfterInitialization

  public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {
    //执行BeanPostProcessors的postProcessAfterInitialization方法,AOP代理就是在这个步骤进行处理的
    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
      Object current = processor.postProcessAfterInitialization(result, beanName);
      if (current == null) {
        return result;
      }
      result = current;
    }
    return result;
  }

方法7:registerDisposableBeanIfNecessary

  protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    //如果不是多例&&需要销毁
    if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
      //如果是单例
      if (mbd.isSingleton()) {
        // Register a DisposableBean implementation that performs all destruction
        // work for the given bean: DestructionAwareBeanPostProcessors,
        // DisposableBean interface, custom destroy method.
        //
        registerDisposableBean(beanName,
            new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
      }
      else {
        // A bean with a custom scope...
        //根据自定义的Scope ,注册销毁回调方式
        Scope scope = this.scopes.get(mbd.getScope());
        if (scope == null) {
          throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
        }
        scope.registerDestructionCallback(beanName,
            new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
      }
    }
  }

requiresDestruction(bean, mbd),见方法8详解

方法8:requiresDestruction

  protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
    //当前bean不是null
     // 1.DisposableBeanAdapter.hasDestroyMethod(bean, mbd):判断bean是否有destroy方法
     // 2.hasDestructionAwareBeanPostProcessors():判断当前BeanFactory是否注册过DestructionAwareBeanPostProcessor
     // 3.DisposableBeanAdapter.hasApplicableProcessors:是否存在适用于bean的DestructionAwareBeanPostProcessor
    return (bean.getClass() != NullBean.class &&
        (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
            DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
  }

DisposableBeanAdapter.hasDestroyMethod(bean, mbd),见方法9详解

DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()),见方法10详解

方法9:hasDestroyMethod

    public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) {
    //bean实现了DisposableBean 或AutoCloseable接口
    if (bean instanceof DisposableBean || bean instanceof AutoCloseable) {
      return true;
    }
    //获取销毁方法名称
    String destroyMethodName = beanDefinition.getDestroyMethodName();
    //如果自定销毁方法名称为 "(inferred)"
    if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName)) {
      //判断是否有close或shutdown方法
      return (ClassUtils.hasMethod(bean.getClass(), CLOSE_METHOD_NAME) ||
          ClassUtils.hasMethod(bean.getClass(), SHUTDOWN_METHOD_NAME));
    }
    return StringUtils.hasLength(destroyMethodName);
  }

方法10:hasApplicableProcessors

  public static boolean hasApplicableProcessors(Object bean, List<BeanPostProcessor> postProcessors) {
    if (!CollectionUtils.isEmpty(postProcessors)) {
      //遍历后置处理器
      for (BeanPostProcessor processor : postProcessors) {
        //如果有类型为DestructionAwareBeanPostProcessor的后置处理器
        if (processor instanceof DestructionAwareBeanPostProcessor) {
          DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
          //判断是否需要由这个后置处理器进行销毁
          if (dabpp.requiresDestruction(bean)) {
            return true;
          }
        }
      }
    }
    return false;
  }

总结

到此,整个bean的创建流程就结束了。

1、对当前Bean实现不同的Aware接口,对不同的属性值进行填充

2、执行BeanPostProcessors的postProcessBeforeInitialization方法,可能会返回新的对象值。

3、调用执行自定义的初始化方法,如果当前Bean实现了InitializingBean接口,则调用afterPropertiesSet方法

4、执行BeanPostProcessors的postProcessAfterInitialization方法,AOP代理就是在这个步骤进行处理的

5、注册销毁相关方法,会在IOC销毁流程中进行回调。

————————————————

版权声明:本文为CSDN博主「@猪大肠」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_45031612/article/details/128177069

目录
相关文章
|
3天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
15 2
|
19天前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
9天前
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
35 9
|
18天前
|
XML 缓存 Java
搞透 IOC、Spring IOC ,看这篇就够了!
本文详细解析了Spring框架的核心内容——IOC(控制反转)及其依赖注入(DI)的实现原理,帮助读者理解如何通过IOC实现组件解耦,提高程序的灵活性和可维护性。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
9天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
22 0
|
1月前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
108 5
|
30天前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
65 0
|
3月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
5月前
|
XML Java 数据格式
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
46 1
|
2月前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
210 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)