SpringIOC初始化過程--詳解

專注後端發表於2019-05-09

SpringIOC初始化過程

相信大家都知道Spring這個東西,我們經常來用他一些特性,比如說他的AOP,IOC,那今天就帶大家解析下SpringIOC的載入過程。

我們來看一個例子

    AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(JobService.class);
        for (String beanname:context.getBeanDefinitionNames())
        {
            System.out.println("--------"+beanname);
        }
        System.out.println("context.getBean(JobService.class) = " + context.getBean(JobService.class));

 這點程式碼很簡單  初始化bean,然後再來拿bean,我們點進AnnotationConfigApplicationContext來看

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses)
{
   this();
   register(annotatedClasses);
   refresh();
}
進⼊之後 會呼叫 this()預設無參構造方法
public AnnotationConfigApplicationContext() {
   this.reader = new AnnotatedBeanDefinitionReader(this);
   this.scanner = new ClassPathBeanDefinitionScanner(this);
}
調⽤這個⽆參構造⽅法的同時 他會呼叫⽗類的構造方法,在呼叫父類構造⽅方法時 他new了一個物件

public
GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); }
也就是 DefaultListableBeanFactory,當然 這個就是所謂我們平常所說的 bean工廠,其父類就是 BeanFactory,BeanFactory有很多子類,DefaultListableBeanFactory就是其中一個⼦類。 那麼 bean的⽣命週期是圍繞那個⽅法呢,就是refresh()⽅法。也就是bean的整個生命週期是圍繞refresh() 來進行的

在refresh()我們可以看到

public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // 準備好重新整理上下文.
      prepareRefresh();

      // 返回一個Factory 為什麼需要返回一個工廠  因為要對工廠進行初始化
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // 準備bean工廠,以便在此上下文中使用。
      prepareBeanFactory(beanFactory);

      try {
         // 允許在上下文子類中對bean工廠進行後處理。 在spring5  並未對此介面進行實現
         postProcessBeanFactory(beanFactory);

         // 在spring的環境中去執行已經被註冊的 Factory processors
         //設定執行自定義的postProcessBeanFactory和spring內部自己定義的
         invokeBeanFactoryPostProcessors(beanFactory);

         // 註冊postProcessor
         registerBeanPostProcessors(beanFactory);

         // 初始化此上下文的訊息源。
         initMessageSource();

         // 初始化此上下文的事件多播程式。
         initApplicationEventMulticaster();

         // 在特定上下文子類中初始化其他特殊bean。
         onRefresh();

         //檢查偵聽器bean並註冊它們。
         registerListeners();

         // 例項化所有剩餘的(非懶載入)單例。
         //new 單例物件
         finishBeanFactoryInitialization(beanFactory);

         // 最後一步:釋出相應的事件
         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();
      }
   }
}

那麼這裡面最重要就是finishBeanFactoryInitialization(beanFactory);這個方法就是描述 spring的一個bean如何初始化

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // Initialize conversion service for this context.
   if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
      beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
   }

   // Register a default embedded value resolver if no bean post-processor
   // (such as a PropertyPlaceholderConfigurer bean) registered any before:
   // at this point, primarily for resolution in annotation attribute values.
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {
      getBean(weaverAwareName);
   }

   // Stop using the temporary ClassLoader for type matching.
   beanFactory.setTempClassLoader(null);

   // Allow for caching all bean definition metadata, not expecting further changes.
   beanFactory.freezeConfiguration();

   // 例項化所有單例物件
   beanFactory.preInstantiateSingletons();
}

可以看到前面是一些判斷 最重要的就是最後一個方法 beanFactory.preInstantiateSingletons();我們看下preInstantiateSingletons()方法,它是ConfigurableListableBeanFactory這個介面的一個方法 我們直接來看這個介面的實現 是由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.
   //所有bean的名字
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

   // Trigger initialization of all non-lazy singleton beans...
   for (String beanName : beanNames) {
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         if (isFactoryBean(beanName)) {
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
               final 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);
         }
      }
   }

我們可以看到用

List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

來儲存bean的名字,那this.beanDefinitionNames是一個什麼東西

/** List of bean definition names, in registration order */
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

可以看到是beanDefinition的一個名字,那beanDefinition是個什麼呢?它是spring當中非常重要的一個概念,在這裡簡單的提一嘴 我們傳統用純java的方式怎麼new物件 是 Student stu=new Student();的方式來例項化物件,但是要交給spring的話,

先通過springScan的方式掃描到類,當他掃描到的時候 他會去new一個beanDefinition物件 他有很多子類 比如說 GenericBeanDefinition generic=new GenericBeanDefinition();然後他會把掃描到的類的各種資訊給拿出來,比如說Student的名字是什麼:

GenericBeanDefinition generic=new GenericBeanDefinition();
    generic.setBeanClassName("studentService"); 類的名字
    generic.setBeanClass(StudentService.class); 類路徑
    generic.isSingleton(); 包括是單例還是原型

等等很多很多,然後把這個物件放到哪裡呢? 在DefaultListableBeanFactory中有一個Map,叫做

private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

就放到這個Map當中 也就是

beanDefinitionMap.put("studentService",generic)這樣放進去之後,spring會看你有沒有呼叫擴充介面,擴充介面我們到後面再說 如果沒有擴充介面,就會繼續呼叫我們剛剛接著繼續的 preInstantiateSingletons()方法,這個方法來完成bean的例項化 總的一句話 BeanDefinition就是用來描述bean的,當然BeanDefinition的知識不僅僅是這些,今天只是簡單提一嘴

那麼我們現在繼續 beanDefinitionNames也就是剛剛那個Map中Key的集合,然後開始迴圈

//觸發所有非延遲載入單例beans的初始化,只要步驟呼叫getBean
//根據List名字從Map當中把BeanDefinition依次拿出來開始new物件
for (String beanName : beanNames) {
  //合併父BeanDefinition
  //通過Map的名字拿BeanDefinition
   RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    //判斷當前類是否抽象 是否為單例  是否為懶載入  如果條件都成立 則繼續
   if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
     //判斷該類是否為FactoryBean FactoryBean這裡不進行講解 不懂得朋友可以去了解下
     //如果不是FactoryBean
      if (isFactoryBean(beanName)) {
         Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
         if (bean instanceof FactoryBean) {
            final 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
         getBean(beanName);
      }
   }
}
@Override
//空方法
public Object getBean(String name) throws BeansException {
   return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

  /**
  *通過name獲取beanName。這裡不使用name直接做beanName
  * name可能會以&字元開頭,表用呼叫者想獲取FactoryBean本身,而非FactoryBean
  *實現類所建立的bean。在BeanFactory中,FactoryBean的實現類和其他的bean儲存方式是一致的即
  * <beanName, bean> ,beanName中沒有&字元的。所以我們需要將name的首字母&移除,這樣才能取到
  *FactoryBean例項
  */
   final String beanName = transformedBeanName(name);
   Object bean;

   // Eagerly check singleton cache for manually registered singletons.
   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 = 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 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);
      }

      try {
         final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         checkMergedBeanDefinition(mbd, beanName, args);

         // 一個註解叫@DependsOn:A類建立 必須B類建立出來再建立A類
         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()) {
           //真正開始建立物件
            sharedInstance = getSingleton(beanName, () -> {
               try {
                  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);
         }

         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();
            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, () -> {
                  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;
}

Object sharedInstance = getSingleton(beanName);重點為這行程式碼,我們點進去getSingleton(beanName)這個方法來看

@Override
@Nullable
public Object getSingleton(String beanName) {
   return getSingleton(beanName, true);
}

/**
 * Return the (raw) singleton object registered under the given name.
 * <p>Checks already instantiated singletons and also allows for an early
 * reference to a currently created singleton (resolving a circular reference).
 * @param beanName the name of the bean to look for
 * @param allowEarlyReference whether early references should be created or not
 * @return the registered singleton object, or {@code null} if none found
 */
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
  
   Object singletonObject = this.singletonObjects.get(beanName);
  
      
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      synchronized (this.singletonObjects) {
         singletonObject = this.earlySingletonObjects.get(beanName);
         if (singletonObject == null && allowEarlyReference) {
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            if (singletonFactory != null) {
               singletonObject = singletonFactory.getObject();
               this.earlySingletonObjects.put(beanName, singletonObject);
               this.singletonFactories.remove(beanName);
            }
         }
      }
   }
   return singletonObject;
}

正在要new一個物件的時候 他會呼叫getSingleton方法,那麼在這個方法中

Object singletonObject = this.singletonObjects.get(beanName);

這行程式碼是本質,那他是什麼東西 我們點進來看

/** Cache of singleton objects: bean name --> bean instance */
//用於存放完全初始化好的bean從該快取中取出bean可以直接使用
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

很明顯 他就是個Map ConcurrentHashMap執行緒安全的Map,什麼意思 這個Map也就是我們常常說說的Spring的容器 如果從微觀角度來講 沒錯spring容器就是這個Map,如果從巨集觀上講,他就不能稱之為map 我希望大家能理解什麼意思,因為spring環境包含很多元件,各種元件包含在一起以及singletonObjects以及一些後置處理器配合完成一些工作我們稱之為Spring容器。

singletonObjects 是什麼?沒錯他就是單例池 他什麼要在單例池拿?為什麼要呼叫他?

因為他要解決Spring當中的迴圈依賴問題,相信大家既然有看原始碼的能力,相信大家也明白什麼是迴圈依賴這裡不再細說

在這個類裡也有介紹

/** Cache of early singleton objects: bean name --> bean instance */
//存放原始的bean物件用於解決迴圈依賴,注意:存到裡面的物件還沒被填充到屬性
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

什麼意思 一個bean放到singletonObjects之後,把一個物件new出來之後,如果這個物件要迴圈引用那spring就會先把他放到earlySingletonObjects這個當中.get是因為怕物件已經放到early當中所以先去get一遍,這裡也只是簡單題一嘴

那我們繼續看

if (sharedInstance != null && args == null) {如果條件成立的話

bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);直接返回撥

如果條件不成立直接else

if (isPrototypeCurrentlyInCreation(beanName)) 判斷這個類是否正在建立,什麼意思 因為spring正在建立一類的時候他會進行標識這個類我正在建立中,然後獲取bean工廠

BeanFactory parentBeanFactory = getParentBeanFactory();這裡不重要

我們繼續來看

sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } 到這一步的時候,才開始真正建立物件,這裡又一個getSingleton這個方法跟上面那個不是同一個方法,這個地方用到lambdas表示式,我們點進去看這個getSingleton

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(beanName, "Bean name must not be null");
   synchronized (this.singletonObjects) {
      Object singletonObject = this.singletonObjects.get(beanName);
      if (singletonObject == null) {
         if (this.singletonsCurrentlyInDestruction) {
            throw new BeanCreationNotAllowedException(beanName,
                  "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                  "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
         }
         if (logger.isDebugEnabled()) {
            logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
         }
         beforeSingletonCreation(beanName);
         boolean newSingleton = false;
         boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
         if (recordSuppressedExceptions) {
            this.suppressedExceptions = new LinkedHashSet<>();
         }
         try {
            singletonObject = singletonFactory.getObject();
            newSingleton = true;
         }
         catch (IllegalStateException ex) {
            // Has the singleton object implicitly appeared in the meantime ->
            // if yes, proceed with it since the exception indicates that state.
            singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
               throw ex;
            }
         }
         catch (BeanCreationException ex) {
            if (recordSuppressedExceptions) {
               for (Exception suppressedException : this.suppressedExceptions) {
                  ex.addRelatedCause(suppressedException);
               }
            }
            throw ex;
         }
         finally {
            if (recordSuppressedExceptions) {
               this.suppressedExceptions = null;
            }
            afterSingletonCreation(beanName);
         }
         if (newSingleton) {
            addSingleton(beanName, singletonObject);
         }
      }
      return singletonObject;
   }
}

Object singletonObject = this.singletonObjects.get(beanName);

這裡關鍵:

第一個getSingleton:單例池拿 拿不到到快取池拿,拿不到返回null 第二個:也是先從單例池拿 如果為null, if (this.singletonsCurrentlyInDestruction)判斷物件有沒有開始建立,

然後 beforeSingletonCreation(beanName);我們點進去來看

protected void beforeSingletonCreation(String beanName) {
        if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
    }

singletonsCurrentlyInCreation是什麼意思

/** Names of beans that are currently in creation */
private final Set<String> singletonsCurrentlyInCreation =
      Collections.newSetFromMap(new ConcurrentHashMap<>(16));

也是一個Lsit,什麼意思 把它放到這個List當中表示正在建立

緊接著呼叫createBean(beanName, mbd, args);開始建立物件

我們來看createBean

@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.
      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 {
      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);
   }
}

到這裡 不要以為完了,其實還沒完最重要的部分

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

這個是第一次呼叫spring的後置處理器,spring的生命週期一共圍繞了9個後置處理器,這個是第一個

我們先不管這些後置處理器是幹嘛的 先把他找出來我們點進resolveBeforeInstantiation

@Nullable
protected Object  resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
   Object bean = null;
   if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
      // Make sure bean class is actually resolved at this point.
      if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
         Class<?> targetType = determineTargetType(beanName, mbd);
         if (targetType != null) {
            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
            if (bean != null) {
               bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
            }
         }
      }
      mbd.beforeInstantiationResolved = (bean != null);
   }
   return bean;
}

bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);點進來看

@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
         if (result != null) {
            return result;
         }
      }
   }
   return null;
}

他會先拿出來所有後置處理器 然後判斷是不是屬於他

我們返回剛剛

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

在doCreateBean裡面呼叫第二個後置處理器,我這裡都不再一一尋找了,直接列出來吧

 

第一次:InstantiationAwareBeanPostProcessor --postProcessBeforeInstantiation

第二次:SmartInstantiationAwareBeanPostProcessor—determineCandidateConstructors—由後置處理器決定返回那些構造方法

第三次:MergedBeanDefinitionPostProcessor——postProcessMergedBeanDefinition------快取的

第四次:SmartInstantiationAwareBeanPostProcessor—getEarlyBeanReference----把物件放到Early當中--處理迴圈引用

第五次:InstantiationAwareBeanPostProcessor—postProcessAfterInstantiation---判斷要不要填充屬性

第六次:InstantiationAwareBeanPostProcessor—postProcessPropertyValues—處理屬性的值

第七次:BeanPostProcessor—postProcessBeforeInitialization —處理AOP

第八次:BeanPostProcessor----postProcessAfterInitialization

第九次為銷燬

 

那麼到這裡一個完整的springBean的初始化。

 

轉載需標明出處 謝謝,體諒下原創,不容易。

相關文章