【spring源码深度解析】:BeanFactory和ApplicationContext之ApplicationContext

文章略长,且只展示了部分核心方法的源码实现,如果有没有表述清楚或不能理解的地方,欢迎在评论区指出

  • 系列文章目录
    • 【spring源码深度解析】开篇:我对于spring框架的理解
    • 【spring源码深度解析】:BeanFactory和ApplicationContext之BeanFactory
    • 【spring源码深度解析】:BeanFactory和ApplicationContext之ApplicationContext
    • 【spring源码深度解析】:事务
  • 附录
    • 【spring源码深度解析】idea下载spring源码,本地构建项目
    • 【spring源码深度解析】:循环依赖

      文章概览

      • 找到启动的ApplicationContext类
      • AbstractApplicationContext
        • 1.refreshBeanFactory(刷新BeanFactory)
          • DefaultBeanDefinitionDocumentReader
        • 2.finishBeanFactoryInitialization(创建所有非懒加载的单例bean)

找到启动的ApplicationContext类

本篇文章以springMVC+tomcat的项目带大家解读ApplicationContext相关源码,虽然现在大家都更多的使用springboot项目,但是springboot的宗旨是简化配置,更快速的部署,所以它与Spring的区别其实主要是在加载配置这一部分,加载后的工作其实一模一样(其实就是二者基于同一个抽象ApplicationContext,只是各自实现了读取配置的方法)

在springMVC web项目的web.xml中,必有这么一段配置:

<servlet>
   <description>spring mvc servletdescription>
   <servlet-name>springservlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
   <init-param>
      <param-name>contextConfigLocationparam-name>
      <param-value>
         classpath:spring-mvc.xml
      param-value>
   init-param>
   <load-on-startup>1load-on-startup>
servlet>

表明tomcat会创建一个DispatcherServlet类型的servlet,然后会调用Servlet的init接口进行初始化,接口的实现里会调用该方法(tomcat和springmvc是如何协同工作的内容放在讲springmvc的时候再说)

//方法位于DispatcherServlet的父类FrameworkServlet中
protected WebApplicationContext createWebApplicationContext(@Nullable ApplicationContext parent) {
   //默认是XmlWebApplicationContext.class
   Class<?> contextClass = getContextClass();
   if (this.logger.isDebugEnabled()) {
      this.logger.debug("Servlet with name '" + getServletName() +
            "' will try to create custom WebApplicationContext context of class '" +
            contextClass.getName() + "'" + ", using parent context [" + parent + "]");
   }
   if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
      throw new ApplicationContextException(
            "Fatal initialization error in servlet with name '" + getServletName() +
            "': custom WebApplicationContext class [" + contextClass.getName() +
            "] is not of type ConfigurableWebApplicationContext");
   }
   //反射创建实例
   ConfigurableWebApplicationContext wac =
         (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);

   wac.setEnvironment(getEnvironment());
   wac.setParent(parent);
   //即web.xml中的spring-mvc.xml配置文件地址
   String configLocation = getContextConfigLocation();
   if (configLocation != null) {
      wac.setConfigLocation(configLocation);
   }
   configureAndRefreshWebApplicationContext(wac);

   return wac;
}

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {
   if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
      // The application context id is still set to its original default value
      // -> assign a more useful id based on available information
      if (this.contextId != null) {
         wac.setId(this.contextId);
      }
      else {
         // Generate default id...
         wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
               ObjectUtils.getDisplayString(getServletContext().getContextPath()) + '/' + getServletName());
      }
   }

   wac.setServletContext(getServletContext());
   wac.setServletConfig(getServletConfig());
   wac.setNamespace(getNamespace());
   wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));

   // The wac environment's #initPropertySources will be called in any case when the context
   // is refreshed; do it eagerly here to ensure servlet property sources are in place for
   // use in any post-processing or initialization that occurs below prior to #refresh
   ConfigurableEnvironment env = wac.getEnvironment();
   if (env instanceof ConfigurableWebEnvironment) {
      ((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig());
   }

   postProcessWebApplicationContext(wac);
   applyInitializers(wac);
   //!!!重点,启动WebApplicationContext
   wac.refresh();
}

可以发现如果没有特别设置WebApplicationContext的具体类型,默认就是创建XmlWebApplicationContext对象,并调用其refresh方法。
按住ctrl+alt键,然后鼠标点击wac.refresh();中的refresh方法可以发现有三个实现类
【spring源码深度解析】:BeanFactory和ApplicationContext之ApplicationContext_第1张图片

而XmlWebApplicationContext继承自AbstractApplicationContext(双击类名,ctrl+h)
【spring源码深度解析】:BeanFactory和ApplicationContext之ApplicationContext_第2张图片

所以查看AbstractApplicationContext的实现

说个spring的代码编写习惯:一般重要的接口,如BeanFactory、ApplicationContext等都会有个对应的抽象类,名字为Abstract+接口名,对接口方法的实现时会统一实现逻辑,然后提供一些模板(钩子)方法留给子类去实现。抽象类一般是我们实际使用的类的父类,如果你不知道该选择哪个类去看接口的实现,一般选择抽象类即可

AbstractApplicationContext

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      //设置下启动时间,标记状态为活跃,初始化配置资源并校验等
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      //让子类去刷新(即启动)内部的bean factory,方法内有两个模板方法:
      //refreshBeanFactory(重点1)
      //getBeanFactory(该方法在上一篇讲bean factory的末尾有提过,就是返回一个DefaultListableBeanFactory类型的成员变量)
      
      //!!!obtainFreshBeanFactory方法执行完后,配置里的bean信息就被转成一个个BeanDefination存放在BeanFactory中,但还未创建任何bean
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      //给beanFactory配置一些属性,注册一些默认bean
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         //模板方法,让子类可以在执行下一步之前做一些操作
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         //执行所有注册的BeanFactoryPostProcessor,即获取成员变量List,进行一些一些排序判断后,遍历执行其postProcessBeanFactory(beanFactory)方法
         //BeanFactoryPostProcessor和下面的BeanPostProcessor其实都是一些回调接口,来实现用户对BeanFactory,Bean的特殊处理
         //由于这里是刷新BeanFactory,所以要执行BeanFactoryPostProcessor,而创建bean需要在最后面执行,所以只是注册BeanPostProcessor但不执行       
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         //获取beanFactory中所有class为BeanPostProcessor.class的bean,也会进行一番排序后,遍历调用beanFactory.addBeanPostProcessor(postProcessor)注册到beanFactory中
         //就是为了在bean创建时进行一些处理,说明beanFactory在创建bean时会调用注册的BeanPostProcessor的相关方法
         registerBeanPostProcessors(beanFactory);

         // Initialize message source for this context.
         //省略
         initMessageSource();

         // Initialize event multicaster for this context.
         //省略
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         //模板方法,子类做一些特殊处理,省略
         onRefresh();

         // Check for listener beans and register them.
         //省略
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         //(重点2)实例化所有非懒加载的单例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();
      }
   }
}

上面的方法很长,逻辑也很多,所以重点提取了两个核心方法来讲解

1.refreshBeanFactory(刷新BeanFactory)

实现方法在XmlWebApplicationContext的父类AbstractRefreshableApplicationContext中

@Override
protected final void refreshBeanFactory() throws BeansException {
    //把之前的BeanFactory关闭掉
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
       //new DefaultListableBeanFactory(getInternalParentBeanFactory())
       //上一篇BeanFactory中最后提到了DefaultListableBeanFactory,看看对它做了些啥操作
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());
      //设置是否允许bean覆盖,beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
      //设置是否允许bean循环引用,beanFactory.setAllowCircularReferences(this.allowCircularReferences);
      //bean覆盖很简单,我定义两个名字一样的bean,第二个bean是覆盖前一个呢还是跳过?
      //bean循环引用比较复杂,请看系列文章里的专题(建议看完bean的完整创建逻辑后再去看)
      customizeBeanFactory(beanFactory);
      //!!!重点,加载配置资源,转化为BeanDefinition对象
      loadBeanDefinitions(beanFactory);
      this.beanFactory = beanFactory;
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}

查看loadBeanDefinitions方法的实现
(AnnotationConfigWebApplicationContext就是文章开头说的springboot使用的基于注解来配置的ApplicationContext,所以它和springMVC默认使用的XmlWebApplicationContext就是各自实现了loadBeanDefinitions方法)
【spring源码深度解析】:BeanFactory和ApplicationContext之ApplicationContext_第3张图片

进入到XmlWebApplicationContext中

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
   // Create a new XmlBeanDefinitionReader for the given BeanFactory.
   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

   // Configure the bean definition reader with this context's
   // resource loading environment.
   beanDefinitionReader.setEnvironment(getEnvironment());
   beanDefinitionReader.setResourceLoader(this);
   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

   // Allow a subclass to provide custom initialization of the reader,
   // then proceed with actually loading the bean definitions.
   initBeanDefinitionReader(beanDefinitionReader);
   loadBeanDefinitions(beanDefinitionReader);
}

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
   String[] configLocations = getConfigLocations();
   if (configLocations != null) {
      for (String configLocation : configLocations) {
         reader.loadBeanDefinitions(configLocation);
      }
   }
}

搭建了Spring源码的同学跟着reader.loadBeanDefinitions(configLocation);实现走,最终会走到这(由于中间跳转过程较多,且无特别需要注意的地方,篇幅有限,就不贴出了,只需要知道会根据configLocation读取xml文件为InputSource,然后转化为Document对象,然后获取Element对象,其实就是在解析xml文件)

DefaultBeanDefinitionDocumentReader

/**
 * Register each bean definition within the given root {@code } element.
 * Element指的就是这个最外层的beans元素
 */
protected void doRegisterBeanDefinitions(Element root) {
   // Any nested  elements will cause recursion in this method. In
   // order to propagate and preserve  default-* attributes correctly,
   // keep track of the current (parent) delegate, which may be null. Create
   // the new (child) delegate with a reference to the parent for fallback purposes,
   // then ultimately reset this.delegate back to its original (parent) reference.
   // this behavior emulates a stack of delegates without actually necessitating one.
   BeanDefinitionParserDelegate parent = this.delegate;
   this.delegate = createDelegate(getReaderContext(), root, parent);
    //是否是默认命名空间,即"beans","import", "alias", "bean",这里是根结点,一般是beans
   if (this.delegate.isDefaultNamespace(root)) {
       //
      String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
      if (StringUtils.hasText(profileSpec)) {
         String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
               profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
         if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
            if (logger.isInfoEnabled()) {
               logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
                     "] not matching: " + getReaderContext().getResource());
            }
            return;
         }
      }
   }

   preProcessXml(root);
   //看这个方法
   parseBeanDefinitions(root, this.delegate);
   postProcessXml(root);

   this.delegate = parent;
}

/**
 * Parse the elements at the root level in the document:
 * "import", "alias", "bean".
 * @param root the DOM root element of the document
 */
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    //如果是根结点
   if (delegate.isDefaultNamespace(root)) {
      NodeList nl = root.getChildNodes();
      //遍历子节点
      for (int i = 0; i < nl.getLength(); i++) {
         Node node = nl.item(i);
         if (node instanceof Element) {
            Element ele = (Element) node;
            //如果是"beans","import", "alias", "bean"
            if (delegate.isDefaultNamespace(ele)) {
                //根据四种情况分别处理
                //1.如果是beans,再调用doRegisterBeanDefinitions方法
                //2.如果是import,调用更之前的方法再解析xml文件
                //3.如果是alias,就获取name和alias属性值,调用bean factory的registerAlias(name, alias)注册别名进去
                //4.如果是bean,获取所有属性值并存储到GenericBeanDefinition对象(成员变量与属性一一对应),调用bean factory的registerBeanDefinition(beanName, definitionHolder)注册进去
                //(beanName默认为id属性,如果没配置name属性但配置了alias属性,取别名的第一个,还为空就通过BeanDefinitionReaderUtils.generateBeanName方法生成默认的)
               parseDefaultElement(ele, delegate);
            }
            else {
                //!!!重点,自定义解析
               delegate.parseCustomElement(ele);
            }
         }
      }
   }
   else {
      delegate.parseCustomElement(root);
   }
}

看命名空间是不是默认的,按住ctrl键,鼠标移到 delegate.parseCustomElement(ele)方法会根据命名空间找到对应的NamespaceHandler实现类,再调用其parse方法解析element。具体逻辑为:spring会读取所有META-INF/spring.handlers文件里的内容,并维护一个namespace
->Handler实现类的map,如下图,然后根据element的命名空间找到对应handler,比如 />对应namespace为http://www.springframework.org/schema/aop,则对应handler为AopNamespaceHandler
(这里的命名有个约定俗成的规定,< xx:…/>由对应的xxNamespaceHandler处理,如果你要看dubbo标签如何解析的,就去看DubboNamespaceHandler类)
【spring源码深度解析】:BeanFactory和ApplicationContext之ApplicationContext_第4张图片

好了,解析配置文件的方法就说完了,这一步主要就是把bean标签内容转化成了beanName ->BeanDefination的map,别名 -> beanName的map,并维护到了BeanFactory中,并解析了非默认标签的内容。下面讲第二个重点方法

2.finishBeanFactoryInitialization(创建所有非懒加载的单例bean)

该方法会先添加一些默认bean,然后调用beanFactory.preInstantiateSingletons()方法(上一篇文章最后也有提到过),实现在DefaultListableBeanFactory类中

@Override
public void preInstantiateSingletons() throws BeansException {
   if (logger.isDebugEnabled()) {
      logger.debug("Pre-instantiating singletons in " + this);
   }

   // Iterate over a copy to allow for init methods which in turn register new bean definitions.
   // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

   // Trigger initialization of all non-lazy singleton beans...
   for (String beanName : beanNames) {
       //获得合并的bean定义,比如
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      //抽象类不能创建,所以必须得是非抽象,单例,懒加载的
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
          //对应的bean 继承了FactoryBean接口,其实也会调用getBean(beanName)方法
         if (isFactoryBean(beanName)) {
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
               FactoryBean<?> factory = (FactoryBean<?>) bean;
               boolean isEagerInit;
               //权限相关,忽略
               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                  isEagerInit = AccessController.doPrivileged(
                        (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
                        getAccessControlContext());
               }
               else {
                  isEagerInit = (factory instanceof SmartFactoryBean &&
                        ((SmartFactoryBean<?>) factory).isEagerInit());
               }
               if (isEagerInit) {
                  getBean(beanName);
               }
            }
         }
         else {
            getBean(beanName);
         }
      }
   }

    //如果bean继承了SmartInitializingSingleton接口,就调用其afterSingletonsInstantiated方法,这其实也就是spring留了个口子让我们在bean创建完后实现自定义操作
   // Trigger post-initialization callback for all applicable beans...
   for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
      if (singletonInstance instanceof SmartInitializingSingleton) {
         SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else {
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
}

可以发现其实bean有没有继承FactoryBean接口都会走getBean(beanName)方法,那么接着看

//实现在AbstractBeanFactory中
//我们调用ApplicationContext.getBean其实也就是调用的该方法,最终都会走到doGetBean方法
@Override
public Object getBean(String name) throws BeansException {
   return doGetBean(name, null, null, false);
}

//核心方法,很长,所以看关键的几步
protected <T> T doGetBean(
      String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
      throws BeansException {

   String beanName = transformedBeanName(name);
   Object bean;

   // Eagerly check singleton cache for manually registered singletons.
   //1.从三个缓存中获取(面试常问的三级缓存,其中两个都是为了解决循环依赖)
   Object sharedInstance = getSingleton(beanName);
   if (sharedInstance != null && args == null) {
      if (logger.isDebugEnabled()) {
         if (isSingletonCurrentlyInCreation(beanName)) {
            logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                  "' that is not fully initialized yet - a consequence of a circular reference");
         }
         else {
            logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
         }
      }
      //若bean不是FactoryBean,直接返回sharedInstance,否则做一些处理
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
   }

   else {
      // Fail if we're already creating this bean instance:
      // We're assumably within a circular reference.
      //循环依赖相关
      if (isPrototypeCurrentlyInCreation(beanName)) {
         throw new BeanCurrentlyInCreationException(beanName);
      }

      // Check if bean definition exists in this factory.
      //本BeanFactory没有该bean,就从父BeanFactory看有没有该bean
      BeanFactory parentBeanFactory = getParentBeanFactory();
      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
         // Not found -> check parent.
         String nameToLookup = originalBeanName(name);
         if (parentBeanFactory instanceof AbstractBeanFactory) {
            return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                  nameToLookup, requiredType, args, typeCheckOnly);
         }
         else if (args != null) {
            // Delegation to parent with explicit args.
            return (T) parentBeanFactory.getBean(nameToLookup, args);
         }
         else {
            // No args -> delegate to standard getBean method.
            return parentBeanFactory.getBean(nameToLookup, requiredType);
         }
      }

      if (!typeCheckOnly) {
         markBeanAsCreated(beanName);
      }
      //重点!!!要开始创建bean了
      try {
          //获取合并后的bean定义
         RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         //是抽象类就报错
         checkMergedBeanDefinition(mbd, beanName, args);

         // Guarantee initialization of beans that the current bean depends on.
         //如果该bean依赖其他bean,维护beanName和dependentBeanName(set)的map,然后getBean(dep)去创建依赖bean
         String[] dependsOn = mbd.getDependsOn();
         if (dependsOn != null) {
            for (String dep : dependsOn) {
               if (isDependent(beanName, dep)) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
               }
               registerDependentBean(dep, beanName);
               try {
                  getBean(dep);
               }
               catch (NoSuchBeanDefinitionException ex) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
               }
            }
         }

         // Create bean instance.
         if (mbd.isSingleton()) {
             //2.创建单例bean,主要是一些创建前后的逻辑
            sharedInstance = getSingleton(beanName, () -> {
               try {
                   //3.!!!真正的去创建bean
                  return createBean(beanName, mbd, args);
               }
               catch (BeansException ex) {
                  // Explicitly remove instance from singleton cache: It might have been put there
                  // eagerly by the creation process, to allow for circular reference resolution.
                  // Also remove any beans that received a temporary reference to the bean.
                  destroySingleton(beanName);
                  throw ex;
               }
            });
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
         }
        //其他scope
         else if (mbd.isPrototype()) {
            // It's a prototype -> create a new instance.
            Object prototypeInstance = null;
            try {
               beforePrototypeCreation(beanName);
               prototypeInstance = createBean(beanName, mbd, args);
            }
            finally {
               afterPrototypeCreation(beanName);
            }
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
         }

         else {
            String scopeName = mbd.getScope();
            if (!StringUtils.hasLength(scopeName)) {
               throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
            }
            Scope scope = this.scopes.get(scopeName);
            if (scope == null) {
               throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
            }
            try {
               Object scopedInstance = scope.get(beanName, () -> {
                  beforePrototypeCreation(beanName);
                  try {
                     return createBean(beanName, mbd, args);
                  }
                  finally {
                     afterPrototypeCreation(beanName);
                  }
               });
               bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
            }
            catch (IllegalStateException ex) {
               throw new BeanCreationException(beanName,
                     "Scope '" + scopeName + "' is not active for the current thread; consider " +
                     "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                     ex);
            }
         }
      }
      catch (BeansException ex) {
         cleanupAfterBeanCreationFailure(beanName);
         throw ex;
      }
   }

   // Check if required type matches the type of the actual bean instance.
   if (requiredType != null && !requiredType.isInstance(bean)) {
      try {
         T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
         if (convertedBean == null) {
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
         }
         return convertedBean;
      }
      catch (TypeMismatchException ex) {
         if (logger.isDebugEnabled()) {
            logger.debug("Failed to convert bean '" + name + "' to required type '" +
                  ClassUtils.getQualifiedName(requiredType) + "'", ex);
         }
         throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
      }
   }
   return (T) bean;
}

总结起来该方法就是三步:

  1. getSingleton(beanName):从单例缓存map里获取bean
  2. getSingleton(String beanName, ObjectFactory singletonFactory):创建单例的前置处理,调用singletonFactory接口,即调用第3步方法创建单例,创建单例的后置处理及把bean实例放入1中缓存
  3. createBean(beanName, mbd, args):创建单例

1,2步中有很多都是对循环引用的处理,具体实现请参考本系列文章循环引用专题。

直接看第3步:

//方法实现在AbstractAutowireCapableBeanFactory类中
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   if (logger.isDebugEnabled()) {
      logger.debug("Creating instance of bean '" + beanName + "'");
   }
   RootBeanDefinition mbdToUse = mbd;

   // Make sure bean class is actually resolved at this point, and
   // clone the bean definition in case of a dynamically resolved Class
   // which cannot be stored in the shared merged bean definition.
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }

   // Prepare method overrides.
   try {
      mbdToUse.prepareMethodOverrides();
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }

   try {
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      //这里会调用所有BeanPostProcessor的postProcessBeforeInstantiation方法,可以自己实现自定义操作
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
         return bean;
      }
   }
   catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }

   try {
       //创建bean
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isDebugEnabled()) {
         logger.debug("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
   }
   catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
      // A previously detected exception with proper bean creation context already,
      // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
   }
}

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

   // Instantiate the bean.
   //BeanWrapper就是个反射包装类,持有一个对象,封装了field.set/get之类的方法
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   if (instanceWrapper == null) {
       //1.创建bean实例,获取beanClass的Constructor方法,再根据策略类来创建,一般是直接Constructor.newInstance(args)反射创建
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   //上面就已经反射创建了一个bean实例,下面开始初始化
   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 {
             //又是调用MergedBeanDefinitionPostProcessor类的相关方法修改bean定义
            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.isDebugEnabled()) {
         logger.debug("Eagerly caching bean '" + beanName +
               "' to allow for resolving potential circular references");
      }
      //与上面的三级缓存有关,getEarlyBeanReference就是再次允许SmartInstantiationAwareBeanPostProcessor对bean进行修改,不然还是返回bean
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
   }

   // Initialize the bean instance.
   //初始化bean实例
   Object exposedObject = bean;
   try {
       //2.!!!装配bean,即填充bean的property
       //(1)先调用InstantiationAwareBeanPostProcessor相关方法的逻辑,可见spring给我们留了很多口子
       //(2)从bean定义中获取PropertyValues pvs(其实就是获取所有,能够根据name得到value),如果配置了
       //(2.1)如果是byName则很简单,从pvs中找到那些非简单bean属性数组(即property name对应的成员变量非a primitive, an enum, a String or other CharSequence, a Number, a Date,
      // a URI, a URL, a Locale or a Class;或者是数组,持有对象也不能是简单的)后(因为这些可能是引用的其他bean),遍历getBean(propertyName)获取属性值,填充到pvs
       //(2.2)如果是byType则会调用autowireByType (从pvs中找到那些非简单bean属性数组后)-> resolveDependency -> doResolveDependency,重点看doResolveDependency方法,最后填充到pvs
       //(3)最后调用applyPropertyValues(beanName, mbd, bw, pvs)方法把pvs设置到instanceWrapper中,也就是反射field.set(bean,propertyVal)把属性值设置到bean中
      populateBean(beanName, mbd, instanceWrapper);
      //3.!!!初始化bean,
      //假如bean实现了BeanNameAware,BeanClassLoaderAware,BeanFactoryAware接口,会调用接口方法
      //遍历调用BeanPostProcessor的postProcessBeforeInitialization方法
      //如果bean实现了InitializingBean接口,会调用afterPropertiesSet方法,如果设置了init-method="init",调用该方法
      //遍历调用BeanPostProcessor的postProcessAfterInitialization方法
      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;
}

//org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency
//获取bean依赖属性的值
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
      @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

   InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
   try {
      Object shortcut = descriptor.resolveShortcut(this);
      if (shortcut != null) {
         return shortcut;
      }

      Class<?> type = descriptor.getDependencyType();
      //先看property上有没有@Value注解,有就获取注解的属性值
      Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
      if (value != null) {
         if (value instanceof String) {
            String strVal = resolveEmbeddedValue((String) value);
            BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
            value = evaluateBeanDefinitionString(strVal, bd);
         }
         TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
         return (descriptor.getField() != null ?
               converter.convertIfNecessary(value, type, descriptor.getField()) :
               converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
      }
      //再看property是不是集合,即对应class是不是array,Collection或Map,如果是就要拿到存储对象的class,调用findAutowireCandidates方法,即根据class从BeanFactory中获取所有beanNames,满足条件的就beanFactory.getBean(beanName)
      Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
      if (multipleBeans != null) {
         return multipleBeans;
      }
      //再根据类型获取所有beans(k->beanName,v->bean实例)
      Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
      if (matchingBeans.isEmpty()) {
         if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
         }
         return null;
      }

      String autowiredBeanName;
      Object instanceCandidate;
      //如果符合条件的不止一个
      if (matchingBeans.size() > 1) {
          //1.先看beans里有没有配置
          //2.否则再根据beans中实现了@Priority注解的,获得value属性对应值,取最大的
          //3.否则就要取属性名称与beans中的beanName或别名相同的bean,即
         autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
         if (autowiredBeanName == null) {
            if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
               return descriptor.resolveNotUnique(type, matchingBeans);
            }
            else {
               // In case of an optional Collection/Map, silently ignore a non-unique case:
               // possibly it was meant to be an empty collection of multiple regular beans
               // (before 4.3 in particular when we didn't even look for collection beans).
               return null;
            }
         }
         instanceCandidate = matchingBeans.get(autowiredBeanName);
      }
      else {
          //只有一个就直接获取
         // We have exactly one match.
         Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
         autowiredBeanName = entry.getKey();
         instanceCandidate = entry.getValue();
      }

      if (autowiredBeanNames != null) {
         autowiredBeanNames.add(autowiredBeanName);
      }
      //对找到的bean进行判断
      if (instanceCandidate instanceof Class) {
         instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
      }
      Object result = instanceCandidate;
      if (result instanceof NullBean) {
         if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
         }
         result = null;
      }
      if (!ClassUtils.isAssignableValue(type, result)) {
         throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
      }
      return result;
   }
   finally {
      ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
   }
}

自此bean经历了反射创建,属性赋值,调用初始化方法后就终于创建完成了

中间有些关键方法的源码实现由于篇幅问题并未列出,在循环引用专题里有详细说明,并有流程图展示多个对象互相引用的创建过程,强烈建议再去看下那篇文章,加深下理解

你可能感兴趣的:(spring源码深度解析,spring,java,spring,boot,bean,xml)