Spring IOC: 背景、设计与实现

2021-08-06  本文已影响0人  布拉德老瓜

Spring IOC :背景、设计与实现

1.控制反转

在应用软件中,必不可免的需要使用到大量的对象来相互协作,共同完成业务逻辑的实现。这些对象通常不是各自独立存在的,而是互相依赖。

假设没有一个对象管理的工具,对象的创建会是什么样的情形呢。举个例子:A依赖于B, 那么创建A的过程中,需要在A内部实现set B对象的方法。该方法需要获取B对象(假设是Singleton对象,那么需要先检查是否对象已存在, 不存在则创建并完成存储)。最朴素的方法自然是弄一个全局的map, 然后在每个对象内部需要注入其他对象时,先从map内获取,如果获取不到,就通过new来创建一个被依赖的对象,然后放到map内。但这样耦合度就高了,此事A对象不仅需要完成本身的业务职责,还需要完成被依赖对象B的管理职责。稍有经验的设计者会弄个工厂模式来做这件事,通过工厂来负责对象的创建,被依赖对象就从工厂获取就好了。可是缺点在于,系统中有大量的对象,需要为每个对象来实现一个工厂,这好像有点不太可行。

有了工厂的想法,我们现在可不可以更大胆一点,把所有对象的创建、获取都交给一个工厂来管理。于是就有了IOC的雏形:使用一个map来完成对象的引用,每当需要获取Bean的时候就从map里取,获取不到就创建,然后put到map里。

那么到底什么是IOC?IOC的思想又指导我们怎样去设计软件?
IOC的思想是:将对象的控制权转交给容器,而不是由我们应用程序去主动创建对象(比如在对象内部去new另一个对象)。所以控制反转说白了:就是将对象的管理、被依赖对象的获取交给IOC容器来完成。

2. 设计

2.1 类继承体系

spring的IOC容器接口就是BeanFactory了,它最核心的作用就是创建和获取bean。


beanFactory

除了最基本的容器功能以外,还通过应用上下文来完成对容器功能的扩充,如:从外部获取Bean定义信息、事件机制等。


uml

2.1.1基础容器设计与实现

基础容器的线路是:BeanFactory ==> HierarchicalBeanFactory ==>ConfigurableBeanFactory==>DefaultListableBeanFactory。它定义并实现了基本容器功能:注册bean定义信息,获取bean实例;
这条主线的核心实现是DefaultListableBeanFactory,在这里重点理解这个类的职责与实现。


DefaultListableBeanFactory实现接口与继承关系

可以看到,它实现了BeanFactory、SingletonBeanRegistry、 AliasRegistry三个顶层接口。因此我们分三个部分来讨论。

DefaultListableBeanFactory作为一个功能完整的容器具备了两个方面的能力: 1.创建、存储、获取Bean

  1. 存储BeanDefinition。

2.1.2 应用上下文设计与实现

3.容器启动

3.1 容器启动总览

spring容器启动的核心方法入口时refresh。

    public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            // 记录一些杂项, 不重要
            this.prepareRefresh();
            // 关键。 获取BeanFactory,将beanDefinitions注册到beanFactory中。  
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            // 设置 BeanFactory 的类加载器,添加 BeanPostProcessor
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                // 调用BeanFactoryPostProcessor的postProcessBeanFactory(factory)方法。
                //对于springboot而言,这里有一个关键的postProcessor:ConfigurationClassPostProcessor。它被用来向容器中注册被注解配置的对象信息。他在内部创建一个ConfigurationParser来处理@Component及其衍生注解,@Import @ImportSelect... 。
               //而SpringBoot启动类上@SpringBootApplication注解包含了@ComponntScan, @Component, @ImportSelect。 
              //springboot自动配置是通过selector.selectImports()利用factoryLoader扫描被依赖jar包中META-INF/spring.factories中的自动配置信息来创建自动配置类的,selectImports的调用时机就是parser.processImports()时获取到Import Selector,然后调用。
                this.invokeBeanFactoryPostProcessors(beanFactory);
                // 注册 BeanPostProcessor 的实现类, 这个接口有两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
                // 两个方法分别在 Bean 初始化之前和初始化之后得到执行,AOP的实现就依赖于BeanPostProcessor,当然那是后话
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

3.2 容器实例化

obtainFreshBeanFactory()

创建一个新鲜的BeanFactory,加载注册Bean定义信息。这里所谓的新鲜是指:如果 ApplicationContext 中已经加载过 BeanFactory 了,销毁所有 Bean,关闭 BeanFactory,然后创建一个新的。

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        this.refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
        }

        return beanFactory;
    }
refreshBeanFactory()
    protected final void refreshBeanFactory() throws BeansException {
        //  ApplicationContext 中如果有BeanFactory,销毁所有 Bean,关闭 BeanFactory
        if (this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }
        try {
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());

            //配置allowBeanDefinitionOverriding 和 allowCircularReferences两个属性
            this.customizeBeanFactory(beanFactory);
            // 加载Bean定义信息。典型的行为重要, 但是实现细节不重要。
            // 将加载进来的BeanDefinitions保存在registry的beanDefinitionMap,形式是String:BeanDefinition。key可以是beanName和beanAlias:BeanDefinition.
            this.loadBeanDefinitions(beanFactory);
            synchronized(this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        } catch (IOException var5) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
        }
    }

3.3 准备容器:prepareBeanFactory

设置BeanFacroty的类加载器,为创建Bean做准备。
添加一些BeanPostProcessor。
从读代码的角度来讲,这段不太关键。

 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 设置类加载器
        beanFactory.setBeanClassLoader(this.getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
        // 添加ApplicationContextAwareProcessor, 在实现了 Aware 接口的 bean 被初始化时,由他完成回调
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        // 添加ApplicationListenerDetector,实现了ApplicationListener接口的对象被初始化之后,调用postProcess....来完成事件监听
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

        // 忽略掉手动完成environment等单例对象注册的代码,不然太长了不好看

    }

3.3 finishBeanFactoryInitialization

    public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            // 记录一些杂项, 不重要
            this.prepareRefresh();
            // 关键。 获取BeanFactory,将beanDefinitions注册到beanFactory中。  
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            // 设置 BeanFactory 的类加载器,添加 BeanPostProcessor
            this.prepareBeanFactory(beanFactory);  // 刚写到这

            try {
                this.postProcessBeanFactory(beanFactory);
                // 调用BeanFactoryPostProcessor的postProcessBeanFactory(factory)方法。
                this.invokeBeanFactoryPostProcessors(beanFactory);
                // 注册 BeanPostProcessor 的实现类, 这个接口有两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
                // 两个方法分别在 Bean 初始化之前和初始化之后得到执行,AOP的实现就依赖于BeanPostProcessor,当然那是后话
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

接下来postProcessBeanFactory, invokeBeanFactoryPostProcessors 和后面的initMessageSource、initApplicationEventMulticaster、registerListeners没啥好说的。
registerBeanPostProcessors就是将实现了BeanPostProcessor 接口的类注册到BeanFactory, 在对象被初始化前后分别执行postProcessBeforeInitialization 和 postProcessAfterInitialization。
对于这个IOC容器,我们重点关注的是它是如何创建、管理对象的,这些细节包含在finishBeanFactoryInitialization中。

3.3.1对象的创建过程

在进行finishBeanFactoryInitialization之前,容器已经被实例化,并加载了bean定义信息,同时讲bean被实例化之后需要进行的操作注册到了容器内。
现在重点就来了,如何去创建并初始化bean,bean被实例化后,又如何为其注入属性,完成后处理。

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

        // set conversionService, 非重点
        if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
            beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
        }
        // set valueResolver , 如果没有,则添加值解析器
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
                public String resolveStringValue(String strVal) {
                    return AbstractApplicationContext.this.getEnvironment().resolvePlaceholders(strVal);
                }
            });
        }

        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        String[] var3 = weaverAwareNames;
        int var4 = weaverAwareNames.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String weaverAwareName = var3[var5];
            this.getBean(weaverAwareName);
        }

        beanFactory.setTempClassLoader((ClassLoader)null);
        beanFactory.freezeConfiguration();

        // 关键一步
        beanFactory.preInstantiateSingletons();
    }

finishBeanFactoryInitialization的关键一步在于preInstantiateSingletons。

public void preInstantiateSingletons() throws BeansException {
   // beanDefinitionNames 保存了所有的 beanNames
   List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

   // 下面这个循环,触发所有的非懒加载的 singleton beans 的初始化操作
   for (String beanName : beanNames) {
      // 非抽象、非懒加载的 singletons。
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         if (isFactoryBean(beanName)) {
            // FactoryBean 的话,在 beanName 前面加上 ‘&’ 符号, 实际上要获取factory, 可以先忽略
            final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
            boolean isEagerInit;
            if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
               isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                  @Override
                  public Boolean run() {
                     return ((SmartFactoryBean<?>) factory).isEagerInit();
                  }
               }, getAccessControlContext());
            }
            else {
               isEagerInit = (factory instanceof SmartFactoryBean &&
                     ((SmartFactoryBean<?>) factory).isEagerInit());
            }
            if (isEagerInit) {

               getBean(beanName);
            }
         }
         else {
            // 对于普通的 Bean,只要调用 getBean(beanName) 这个方法就可以进行初始化了
            getBean(beanName);
         }
      }
   }

   // 在上面的一个循环中讲所有的单例对象都实例化了,接下来要对实现了SmartInitializingSingleton接口的对象完成一些善后工作,非重点
   for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
      if (singletonInstance instanceof SmartInitializingSingleton) {
         final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
               @Override
               public Object run() {
                  smartSingleton.afterSingletonsInstantiated();
                  return null;
               }
            }, getAccessControlContext());
         }
         else {
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
}

其实整个方法,核心在于遍历beanName,拿到它的bean定义信息,如果是非抽象、非懒加载的单例,则去调getBean来获取。

getBean(name)
@Override
public Object getBean(String name) throws BeansException {
   return doGetBean(name, null, null, false);  //doGetBean()才是真正干活的
}

// 四个参数: 分别是名称、类型、 创建对象的参数、是否只做类型检查
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
      final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
      throws BeansException {
    //获取bean可以通过名称或者别名来获取,如果是别名,将其转成beanName即可。
   final String beanName = transformedBeanName(name);

   Object bean; 

   // 先检查是否已创建过
   Object sharedInstance = getSingleton(beanName);

   //args != null说明要创建;如果不是,此时对象已经实例化完成了,如果是普通对象,那么最终返回的就是实例化完成了的这个对象;如果是FactoryBean,那么说明是要通过Factory来创建一个对象。
   if (sharedInstance != null && args == null) { 
      if (logger.isDebugEnabled()) {
         if (isSingletonCurrentlyInCreation(beanName)) {
            logger.debug("...");
         }
         else {
            logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
         }
      }
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
   }

   else {
      if (isPrototypeCurrentlyInCreation(beanName)) {
         // 如果是prototype 类型,且正在创建同名的对象,那么抛异常
         throw new BeanCurrentlyInCreationException(beanName);
      }

      // getSingleton没获取到,也没有正在创建的prototype,从父容器中尝试获取,获取到则返回
      BeanFactory parentBeanFactory = getParentBeanFactory();
      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
         String nameToLookup = originalBeanName(name);
         if (args != null) {
            return (T) parentBeanFactory.getBean(nameToLookup, args);
         }
         else {
            return parentBeanFactory.getBean(nameToLookup, requiredType);
         }
      }

      if (!typeCheckOnly) {
         // typeCheckOnly 为 false,将当前 beanName 放入一个 alreadyCreated 的 Set 集合中。
         markBeanAsCreated(beanName);
      }


      // 都没获取到,现在需要创建一个
      try {
         final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         checkMergedBeanDefinition(mbd, beanName, args);
         // 先获取到它depond-on中定义的依赖,在depond-on中定义的依赖与对象的引用依赖有些区别,depons-on是说,需要先有depens-on, 然后才能有当前对象。因此,这里必须要先创建被depends-on的对象。
         String[] dependsOn = mbd.getDependsOn();
         if (dependsOn != null) {
            for (String dep : dependsOn) {
               // depends-on是不可以循环依赖的,举例来说就是:A定义必须先有B才能有A,然后在B里面定义说必须先有A才能有B,这就说不通了。
               if (isDependent(beanName, dep)) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
               }
               // 注册一下依赖关系
               registerDependentBean(dep, beanName);
               // 先初始化被依赖项
               getBean(dep);
            }
         }

         // 如果是 singleton scope 的,创建 singleton 的实例
         if (mbd.isSingleton()) {
            sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
               @Override
               public Object getObject() throws BeansException {
                  try {
                     // 执行创建 Bean,详情后面再说
                     return createBean(beanName, mbd, args);
                  }
                  catch (BeansException ex) {
                     destroySingleton(beanName);
                     throw ex;
                  }
               }
            });
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
         }

         // 如果是 prototype scope 的,创建 prototype 的实例
         else if (mbd.isPrototype()) {
            // It's a prototype -> create a new instance.
            Object prototypeInstance = null;
            try {
               beforePrototypeCreation(beanName);
               // 执行创建 Bean
               prototypeInstance = createBean(beanName, mbd, args);
            }
            finally {
               afterPrototypeCreation(beanName);
            }
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
         }

         // 如果不是 singleton 和 prototype 的话,需要委托给相应的实现类来处理
         else {
            String scopeName = mbd.getScope();
            final 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, new ObjectFactory<Object>() {
                  @Override
                  public Object getObject() throws BeansException {
                     beforePrototypeCreation(beanName);
                     try {
                        // 执行创建 Bean
                        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;
      }
   }

   // 最后,检查一下类型对不对,不对的话就抛异常,对的话就返回了
   if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
      try {
         return getTypeConverter().convertIfNecessary(bean, requiredType);
      }
      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;
}

这个方法很长,但核心逻辑还算比较清楚。


doGetBean

方法中两个比较重要的方法是:getSingleton()和createBean().

getSingleton:获取单例对象
    public Object getSingleton(String beanName) {
        return this.getSingleton(beanName, true);
    }

    // 有3个map, 分别是singletonObject,表示已初始化完成的单例对象 ; earlySingletonObjects,还没初始化完的对象,和 singletonFactories: 还没有实例化,只有单例工厂的单例对象。逻辑相对简单,就像阶级晋升一样。
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
            synchronized(this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }

        return singletonObject != NULL_OBJECT ? singletonObject : null;
    }
核心: createBean()
/**
 * Central method of this class: creates a bean instance,
 * populates the bean instance, applies post-processors, etc.
 * @see #doCreateBean
 */
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
   if (logger.isDebugEnabled()) {
      logger.debug("Creating instance of bean '" + beanName + "'");
   }
   RootBeanDefinition mbdToUse = mbd;

   // 解析BeanDefinition 的 Class
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }

   // 准备方法覆写
   try {
      mbdToUse.prepareMethodOverrides();
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }

   try {
      // 对于实现了TargetSource接口的bean来说,可以在这一步返回代理对象
      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);
   }
   // 重点: 创建实例对象
   Object beanInstance = doCreateBean(beanName, mbdToUse, args);
   if (logger.isDebugEnabled()) {
      logger.debug("Finished creating instance of bean '" + beanName + "'");
   }
   return beanInstance;
}
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }

        // factoryBeanInstanceCache中没有, 创建一个封装了实例对象的wrapper
        if (instanceWrapper == null) {
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        final Object bean = instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null;
        Class<?> beanType = instanceWrapper != null ? instanceWrapper.getWrappedClass() : null;
        mbd.resolvedTargetType = beanType;
        synchronized(mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                } catch (Throwable var17) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
                }

                mbd.postProcessed = true;
            }
        }

        // 提前暴露的singleton,目的是解决循环引用。它是如何解决的呢?到了这一步bean已经被实例化了,只是还没有注入属性。此时如果有另外一个对象需要引用当前对象,那么把这个bean实例注入到另外一个bean就ok了。等到当前bean被注入属性并初始化完成以后,得到的引用就是一个完整的对象。
        boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
        if (earlySingletonExposure) {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
            }

            this.addSingletonFactory(beanName, new ObjectFactory<Object>() {
                public Object getObject() throws BeansException {
                    return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }

        Object exposedObject = bean;

        try {
            // 注入属性
            this.populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
                //初始化bean, 完成各种回调
                exposedObject = this.initializeBean(beanName, exposedObject, mbd);
            }
        } catch (Throwable var18) {
            if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
                throw (BeanCreationException)var18;
            }

            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
        }

        if (earlySingletonExposure) {
            Object earlySingletonReference = this.getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                    String[] dependentBeans = this.getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
                    String[] var12 = dependentBeans;
                    int var13 = dependentBeans.length;

                    for(int var14 = 0; var14 < var13; ++var14) {
                        String dependentBean = var12[var14];
                        if (!this.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.");
                    }
                }
            }
        }

        try {
            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
            return exposedObject;
        } catch (BeanDefinitionValidationException var16) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
        }
    }

该方法中,关键的几步分别是: createBeanInstance、populateBean和initializeBean。

createBeanInstance

创建Bean实例对象:通过反射获取构造方法,判断需要有参还是无参构造器,通过构造器创建对象实例,并包装成InstanceWrapper,不多说

populateBean()填充属性:
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
   // bean 实例的所有属性都在这里了
   PropertyValues pvs = mbd.getPropertyValues();

   if (bw == null) {
      if (!pvs.isEmpty()) {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
      }
      else {
         // Skip property population phase for null instance.
         return;
      }
   }

   // 到这步的时候,bean 实例化完成(通过工厂方法或构造方法),但是还没开始属性设值
   boolean continueWithPropertyPopulation = true;
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { // 实例化之后立即通知的后处理器。通常BeanPostProcessor是在populate完成之后,初始化的时候调用postProcessAfterInitialization,但是有这个后处理器的话,需要调postProcessAfterInstantiation。
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            // 只要有一个返回 false,代表不需要进行后续的属性设值,也不需要再经过其他的 BeanPostProcessor 的处理
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
               continueWithPropertyPopulation = false;
               break;
            }
         }
      }
   }

   if (!continueWithPropertyPopulation) {
      return;
   }

   if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
         mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

      // 通过名字找到所有属性值,这一步执行完,并没有把属性set到当前bean,而是在newPvs里添加了name和value
      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
         autowireByName(beanName, mbd, bw, newPvs);
      }

      // 通过类型装配
      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
         autowireByType(beanName, mbd, bw, newPvs);
      }

      pvs = newPvs;
   }

   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
   boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

   if (hasInstAwareBpps || needsDepCheck) {
      PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      if (hasInstAwareBpps) {
         for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
               // 这里有个非常有用的 BeanPostProcessor : AutowiredAnnotationBeanPostProcessor
               //在设置 Bean 属性之前,允许 BeanPostProcessor 修改属性值 的操作
               // [https://segmentfault.com/a/1190000040451668](https://segmentfault.com/a/1190000040451668)
               // 在这里完成属性值的修改。
               pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
               if (pvs == null) {
                  return;
               }
            }
         }
      }
      if (needsDepCheck) {
         checkDependencies(beanName, mbd, filteredPds, pvs);
      }
   }
   // 设置 bean 实例的属性值
   applyPropertyValues(beanName, mbd, bw, pvs);
}

populateBean中比较关键的点在于: 获取propertyValues, 然后根据name或者type来完成autowire,在autowireByName/Type时,没有直接将属性值设置到bean内部,而是暂时存储在了pvs中。之后获取InstantiationAwareBeanPostProcessor , 来后处理属性值。最后将处理之后的属性值设入到对象内。
autowire是如何实现的可以参考这里

initializeBean

进入doCreateBean最后一个小重点:initializeBean

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged(new PrivilegedAction<Object>() {
         @Override
         public Object run() {
            invokeAwareMethods(beanName, bean);
            return null;
         }
      }, getAccessControlContext());
   }
   else {
      // 如果 bean 实现了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,回调
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      // 初始化方法之前, 回调BeanPostProcessor 的 postProcessBeforeInitialization
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
      // 处理 bean 中定义的 init-method,
      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 的 postProcessAfterInitialization
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }
   return wrappedBean;
}
上一篇下一篇

猜你喜欢

热点阅读