美文网首页
Spring IOC: 背景、设计与实现

Spring IOC: 背景、设计与实现

作者: 布拉德老瓜 | 来源:发表于2021-08-06 23:56 被阅读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三个顶层接口。因此我们分三个部分来讨论。

      1. 实现BeanFactory这条线。BeanFactory下三个接口的功能:
      • ListablebeanFactory:实现Bean的list集合操作功能
      • HierarchicalBeanFactory : 在继承BeanFactory的基础上,定义如何实现BeanFactory的父子关系。
      • AutowireCapableBeanFactory: 定义Bean的自动装配功能
    • 2.SingletonBeanRegistry: 单例bean的注册接口,提供了以名称:Object的方式完成单例Bean的注册、获取功能。
      1. AliasRegistry: 别名注册接口
        这条线的BeanDefinitionRegistry需要留意,提供了以名称:BeanDefinition的方式完成Bean信息的注册、删除、获取功能。

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

    1. 存储BeanDefinition。

    2.1.2 应用上下文设计与实现

    • 另一条是:BeanFactory ==> ListableBeanFactory ==> ApplicationContext ==> ConfigurableApplicationContext, 定义了应用上下文的实现规则,虽然从接口上来看是继承关系,但实际上是应用上下文内部持有了IOC容器。 应用上下文不仅仅是管理对象的创建和获取,还要完成一些高级特性的扩展:从外部资源获取bean定义信息,事件发布.etc。
      常用的应用上下文就是uml中的xml和注解配置应用上下文。

    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;
    }
    

    相关文章

      网友评论

          本文标题:Spring IOC: 背景、设计与实现

          本文链接:https://www.haomeiwen.com/subject/yebmvltx.html