Spring Ioc启动流程分析

上一篇我们解析了设计模式的代理模式,在这里再做一次Spring Ioc启动流程的分析,然后再引入到SpringAOP 的原理上来

ok,我们先看下Spring Ioc启动的大致流程吧

目前Spring 启动流程大致分析如图

在测试类中 ApplicationContext ac = new ClassPathXmlApplicationContext(“applicationContext.xml”);

找到启动的入口:
在这里插入图片描述
在 ClassPathXmlApplicationContext 的实例化方法中,找到refresh() 方法
在这里插入图片描述
在这里插入图片描述
此处调用的是 AbstractApplicitionContext 中的refresh() 方法进入启动,代码如下:

public void refresh() throws BeansException, IllegalStateException {
    
    synchronized (this.startupShutdownMonitor) {
    StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
      // Prepare this context for refreshing.
      // 准备 刷新容器的上下文context信息 注:此 applicationContext是BeanFactory接口的实现类
      //设置容器的启动和激活状态,初始化环境和资源信息
      prepareRefresh();
      // Tell the subclass to refresh the internal bean factory.
      // 创建 beanFactory 容器对象,及初始的一些容器对象
      // 注:beanFactory属性 为 此 applicationContext 对象中的一个属性
      // 加载beanDefinition 信息到 beanFactory(默认是DefaultListableBeanFactory)的 beanDefinitionMap 容器中去
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      // 为 beanFactory 准备一些信息 类加载器classLoader
      // BeanExpressionResolver 表达式解析器
      // BeanPostProcessor bean的后置处理器  
      // 需要忽略的 Aware接口 等
      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);
      try {
       // Allows post-processing of the bean factory in context subclasses.
      // debug进来看是个空方法,什么也没有, do nothing
      // 看了方法的注释意思是 在标准初始化之后 修改 applicationContext的
      // 内部的beanFactory        
      postProcessBeanFactory(beanFactory);
      
      StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
      // Invoke factory processors registered as beans in the context.
      // 调用 BeanFactoryPostProcessor的 postProcessBeanFactory()方法对 beanDefinition 的信息做处理  
      invokeBeanFactoryPostProcessors(beanFactory);
      // Register bean processors that intercept bean creation.
      // 注册 beanPostProcessor 到 beanFactory 中去
       registerBeanPostProcessors(beanFactory);
      // do nothing 
       beanPostProcess.end();
       // Initialize message source for this context.
      // 初始化 MessageSource 用于处理国际化资源
      initMessageSource();
        // Initialize event multicaster for this context.
      // 初始化 应用事件的 多播器-广播器 用于分发应用事件给监听者
       initApplicationEventMulticaster();
       // Initialize other special beans in specific context subclasses.
      // 初始化其他bean和进行其他上下文初始化 主要用于扩展  do nothing 
        onRefresh();
        // Check for listener beans and register them.
      // 注册事件监听器 到 applicationContext/beanFactory 中
       registerListeners();
        // Instantiate all remaining (non-lazy-init) singletons.
      // 完成 beanFactory中普通单例Bean 的创建和初始化, 进入创建bean的流程
       finishBeanFactoryInitialization(beanFactory);
        // Last step: publish corresponding event.
      // 启动完成,资源回收,分发"刷新完成"事件
        finishRefresh();

      }catch (BeansException ex) {
        if (logger.isWarnEnabled()) {
          logger.warn("Exception encountered during context initialization - " +
             "cancelling refresh attempt: " + ex);
        }
        // Destroy already created singletons to avoid dangling resources.
        destroyBeans();
        // Reset 'active' flag.
        cancelRefresh(ex);
        // Propagate exception to caller.
        throw ex;
      }
      finally {
        // Reset common introspection caches in Spring's core, since we
        // might not ever need metadata for singleton beans anymore...
        resetCommonCaches();
        contextRefresh.end();
      }
    }
  }

Spring IOC容器启动步骤 主要就是调用的refresh() 方法中的这13个方法

  1. prepareRefresh();

  2. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

  3. prepareBeanFactory(beanFactory);

  4. postProcessBeanFactory(beanFactory);

  5. invokeBeanFactoryPostProcessors(beanFactory);

  6. registerBeanPostProcessors(beanFactory);

  7. beanPostProcess.end();

  8. initMessageSource();

  9. initApplicationEventMulticaster();

  10. onRefresh();

  11. registerListeners();

  12. finishBeanFactoryInitialization(beanFactory);

  13. finishRefresh();

上面方法全部执行完成之后创建出 ApplicationContext 的实例对象 ac

ac 中含有 beanFactory 的实例对象DefaultListableBeanFactory
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述其中 我们主要分析Spring IOC 中 普通的Bean对象的创建过程

也就是 第12个方法的

主要执行流程为
AbstractApplicationContext.finishBeanFactoryInitialization(beanFactory)---->
DefaultListableBeanFactory.preInstantiateSingletons()—>

AbstractBeanFactory.getBean(String name) —>

AbstractBeanFactory.doGetBean() ----->

AbstractAutowireCapableBeanFactory.createBean()—>

AbstractAutowireCapableBeanFactory.doCreateBean()—>

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
再到 doCreateBean() 方法中的


// doCreateBean() 
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
      // 创建bean 的实例
      instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    Object bean = instanceWrapper.getWrappedInstance();
    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 {
          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.
    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");
      }
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
    // 装配 bean 实例的属性信息
      populateBean(beanName, mbd, instanceWrapper);
      // 实例化 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) {
      Object earlySingletonReference = getSingleton(beanName, false);
      if (earlySingletonReference != null) {
        if (exposedObject == bean) {
          exposedObject = earlySingletonReference;
        }
        else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
          String[] dependentBeans = getDependentBeans(beanName);
          Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
          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 " +
                "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
          }
        }
      }
    }
    // Register bean as disposable.
    try {
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
      throw new BeanCreationException(
          mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }
    return exposedObject;
  }

// 使用反射 创建 bean的实例
instanceWrapper = createBeanInstance(beanName, mbd, args);


/**
   * Create a new instance for the specified bean, using an appropriate instantiation strategy:
   * factory method, constructor autowiring, or simple instantiation.
   * @param beanName the name of the bean
   * @param mbd the bean definition for the bean
   * @param args explicit arguments to use for constructor or factory method invocation
   * @return a BeanWrapper for the new instance
   */
  protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // Make sure bean class is actually resolved at this point.
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
      throw new BeanCreationException(mbd.getResourceDescription(), beanName,
          "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
    }

    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
      return obtainFromSupplier(instanceSupplier, beanName);
    }

    if (mbd.getFactoryMethodName() != null) {
      return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same bean...
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
      synchronized (mbd.constructorArgumentLock) {
        if (mbd.resolvedConstructorOrFactoryMethod != null) {
          resolved = true;
          autowireNecessary = mbd.constructorArgumentsResolved;
        }
      }
    }
    if (resolved) {
      if (autowireNecessary) {
        return autowireConstructor(beanName, mbd, null, null);
      }
      else {
        return instantiateBean(beanName, mbd);
      }
    }
    // Candidate constructors for autowiring?
    // 决定 使用哪些构造函数来 实例化 bean对象
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
      return autowireConstructor(beanName, mbd, ctors, args);
    }
    // Preferred constructors for default construction?
    // 在 beanDefinition 信息中指定优先使用的 构造器
    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实例对象
   * Instantiate the given bean using its default constructor.
   * @param beanName the name of the bean
   * @param mbd the bean definition for the bean
   * @return a BeanWrapper for the new instance
   */
  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);
      }
      BeanWrapper bw = new BeanWrapperImpl(beanInstance);
      initBeanWrapper(bw);
      return bw;
    }
    catch (Throwable ex) {
      throw new BeanCreationException(
          mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
  }

// 装配 bean中的属性 比如: 若在UserServiceImpl 中如果有userDao 这个属性,则在这一步给 userDao 这个属性装配到UserServiceImpl 这个bean的实例对象中去
populateBean(beanName, mbd, instanceWrapper);

// 初始化 bean
exposedObject = initializeBean(beanName, exposedObject, mbd);

初始化initializeBean()方法代码如下:
AbstractAutowireCapableBeanFactory.initializeBean()

/** 
    * @see BeanNameAware
     * @see BeanClassLoaderAware
     * @see BeanFactoryAware
     * @see #applyBeanPostProcessorsBeforeInitialization
     * @see #invokeInitMethods
     * @see #applyBeanPostProcessorsAfterInitialization
     */
  protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
        invokeAwareMethods(beanName, bean);
        return null;
      }, getAccessControlContext());
    }
    else {
    // 调用 Aware 方法 设置容器属性到 bean实例中
       invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
      // 应用 beanPostProcessor 的 初始化前方法增强
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
    //调用 bean的初始化方法  afterPropertiesSet() -- invokeCustomInitMethod
      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()) {
    // 应用 beanPostProcessor 的 初始化后方法的增强
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
  }

至此,bean对应的实例对象创建并初始化完成

第12个方法执行完成 则 所有的bean实例化对象 都被创建并初始化,被放在了DefaultListableBeanFactory 的 Map<String, Object> singletonObjects容器中 ----> 此Map 容器则是常说的Spring Ioc的容器

普通Bean创建流程都是由BeanFactory统一创建,整体流程如下图:
在这里插入图片描述
平时我们自己使用类时创建的对象都是自己手动调用 类的构造方法来创建的,但是在Spring中 相当于是把控制bean对象创建的权限交给了Spring通过反射Constructor 来创建,故而叫做 Inversion of Control 控制反转 是为Spring Ioc

关于BeanPostProcessor 和BeanFactoryPostProcessor

BeanPostProcessor 和 BeanFactoryPostProcess 都是Spring 初始化bean时对外暴露的扩展点。

由上图可看出 BeanFactoryPostProcessor 是针对于BeanDefinition类来进行增强的,允许在容器实例化bean之前读取bean的定义信息(配置元数据),并可以修改,定义一个BeanFactoryPostProcessor 需要实现该接口,并重写
接口方法
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)

而 BeanPostProcessor 是针对于 Bean初始化前后的增强操作,依赖于
postProcessBeforeInitialization(Object bean, String beanName)

postProcessAfterInitialization(Object bean, String beanName)
这两个方法
分别在 bean对象初始化的前和后 增强扩展

而Spring Aop 的增强功能 就是通过 此处的 postProcessAfterInitialization() 初始化后的后置处理来创建 bean的代理对象来实现 切面编程 做增强扩展的

至此,Spring Ioc 的流程分析完成,至于里面还有好多细节的点,还是需要手动去debug层层跟进,调试,记录
总体上Spring Ioc的启动流程大致过程就是这样的,OK,下次我们在来分析Spring AOP 相关的内容吧

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值