Spring源碼閱讀

參考資料:spring源碼深度解析
Spring版本:Spring-4.3.5-RELEASE

吐槽下,老外寫的東西真暈啊,像親媽一樣啰啰嗦嗦幫你考慮了各種情況,然后最好還不忘加一句:
如果你不滿意,還可以拓展?。。?

1.spring 核心代碼

1.1 核心流程初始化過程

非常清晰的模板方法,每一個步驟封裝成一個具體的函數(shù)進行代理,職責清晰明了;

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      //預熱,做準備工作
      prepareRefresh();
 
      // Tell the subclass to refresh the internal bean factory.
      //獲取內(nèi)部的bean factory
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 
      // Prepare the bean factory for use in this context.
      //預熱beanFactory
      prepareBeanFactory(beanFactory);
 
      try {
         // Allows post-processing of the bean factory in context subclasses.
         postProcessBeanFactory(beanFactory);
 
         // Invoke factory processors registered as beans in the context.
         //beanFactory在上下文中注冊bean,核心的代碼就在這里
         invokeBeanFactoryPostProcessors(beanFactory);
 
         // Register bean processors that intercept bean creation.
         // bean創(chuàng)建的時候攔截并注冊bean處理器,這里只創(chuàng)建處理器,真正的創(chuàng)建是在getBean(..)方法里
         registerBeanPostProcessors(beanFactory);
 
         // Initialize message source for this context.
         // 用于支持國際化,比如一些日志的國際化匹配等;
         initMessageSource();
 
         // 為上下文初始化消息傳播工具
         initApplicationEventMulticaster();
 
         // Initialize other special beans in specific context subclasses.
         // 鉤子方法:額外的beans處理方法
         onRefresh();
 
         // Check for listener beans and register them.
         // 注冊監(jiān)聽器
         registerListeners();
 
         // Instantiate all remaining (non-lazy-init) singletons.
         // 實例化非延時加載的bean單例
         finishBeanFactoryInitialization(beanFactory);
 
         // Last step: publish corresponding event.
         // push beans創(chuàng)建完成的消息
         finishRefresh();
      }
 
      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }
 
         // Destroy already created singletons to avoid dangling resources.
         destroyBeans();
 
         // Reset 'active' flag.
         cancelRefresh(ex);
 
         // Propagate exception to caller.
         throw ex;
      }
 
      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}

1.2 spring 類加載的基本類spring DefaultListableBeanFactory UML示意圖:

image.png

1.3 spring bean 創(chuàng)建過程

  • 轉(zhuǎn)換beanName
  • 嘗試從緩存中獲取單例
  • bean本身的實例化
  • 原型模式依賴檢測
  • parentBeanFactory 檢測
  • 將gernerecBeanDefinition 轉(zhuǎn)換成 RootBeanDefination
  • 尋找依賴
  • 根據(jù)scope 初始化(init)對應的bean
  • 類型轉(zhuǎn)換
/**
 * Return an instance, which may be shared or independent, of the specified bean.
 * @param name the name of the bean to retrieve
 * @param requiredType the required type of the bean to retrieve
 * @param args arguments to use when creating a bean instance using explicit arguments
 * (only applied when creating a new instance as opposed to retrieving an existing one)
 * @param typeCheckOnly whether the instance is obtained for a type check,
 * not for actual use
 * @return an instance of the bean
 * @throws BeansException if the bean could not be created
 */
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
      final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
      throws BeansException {
 
   //轉(zhuǎn)換beanName,我們知道在spring中,bean factory的名稱都是類似于 &org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory
   //因此獲取的時候需要進行轉(zhuǎn)換
   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.
      // 檢測當前依賴的類是否正在創(chuàng)建,如果是,則拋出異常
      if (isPrototypeCurrentlyInCreation(beanName)) {
         throw new BeanCurrentlyInCreationException(beanName);
      }
 
      // Check if bean definition exists in this factory.
      // 如果bean配置不存在則只能去父工廠找
      BeanFactory parentBeanFactory = getParentBeanFactory();
      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
         // Not found -> check parent.
         String nameToLookup = originalBeanName(name);
         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 {
         //轉(zhuǎn)換并合并BeanDefinition屬性
         final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         checkMergedBeanDefinition(mbd, beanName, args);
 
         // Guarantee initialization of beans that the current bean depends on.
         // 原型模式的bean需要循環(huán)檢測依賴  防止出現(xiàn)A->B->A 的循環(huán)依賴情況出現(xiàn)
         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);
               getBean(dep);
            }
         }
 
         // Create bean instance.
         // 創(chuàng)建bean實例
         if (mbd.isSingleton()) {
            sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
               @Override
               public Object getObject() throws BeansException {
                  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, new ObjectFactory<Object>() {
                  @Override
                  public Object getObject() throws BeansException {
                     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.
   // 轉(zhuǎn)換bean類型
   if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
      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;
} 

1.4 spring事務隔離級別及事務傳播實現(xiàn)

  • propagation_requierd(spring的事務默認是該級別):如果當前沒有事務,就新建一個事務,如果已存在一個事務中,加入到這個事務中,這是最常見的選擇。
  • propagation_supports:支持當前事務,如果沒有當前事務,就以非事務方法執(zhí)行。
  • propagation_mandatory:使用當前事務,如果沒有當前事務,就拋出異常。
  • propagation_required_new:新建事務,如果當前存在事務,把當前事務掛起。
  • propagation_not_supported:以非事務方式執(zhí)行操作,如果當前存在事務,就把當前事務掛起。
  • propagation_never:以非事務方式執(zhí)行操作,如果當前事務存在則拋出異常。
  • propagation_nested:如果當前存在事務,則在嵌套事務內(nèi)執(zhí)行。如果當前沒有事務,則執(zhí)行與propagation_required類似的操作
 * Create a TransactionStatus for an existing transaction.
 */
private TransactionStatus handleExistingTransaction(
      TransactionDefinition definition, Object transaction, boolean debugEnabled)
      throws TransactionException {
 
    //若為非事務方式,則拋異常
   if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
      throw new IllegalTransactionStateException(
            "Existing transaction found for transaction marked with propagation 'never'");
   }
    
   // 若存在事務,掛起適當前事務
   if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
      if (debugEnabled) {
         logger.debug("Suspending current transaction");
      }
      // 掛起當前事務
      Object suspendedResources = suspend(transaction);
      boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
      return prepareTransactionStatus(
            definition, null, false, newSynchronization, debugEnabled, suspendedResources);
   }
    
   // 掛起當前事務,并新建事務
   if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
      if (debugEnabled) {
         logger.debug("Suspending current transaction, creating new transaction with name [" +
               definition.getName() + "]");
      }
      //掛起當前事務
      SuspendedResourcesHolder suspendedResources = suspend(transaction);
      try {
         boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
         DefaultTransactionStatus status = newTransactionStatus(
               definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
         // 重新開啟事務
         doBegin(transaction, definition);
         prepareSynchronization(status, definition);
         return status;
      }
      catch (RuntimeException beginEx) {
         resumeAfterBeginException(transaction, suspendedResources, beginEx);
         throw beginEx;
      }
      catch (Error beginErr) {
         resumeAfterBeginException(transaction, suspendedResources, beginErr);
         throw beginErr;
      }
   }
     
   // 若當前事務存在,則嵌套執(zhí)行事務
   if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
      if (!isNestedTransactionAllowed()) {
         throw new NestedTransactionNotSupportedException(
               "Transaction manager does not allow nested transactions by default - " +
               "specify 'nestedTransactionAllowed' property with value 'true'");
      }
      if (debugEnabled) {
         logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
      }
      // 判定是否支持事務備份點
      if (useSavepointForNestedTransaction()) {
         // Create savepoint within existing Spring-managed transaction,
         // through the SavepointManager API implemented by TransactionStatus.
         // Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
         DefaultTransactionStatus status =
               prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
         // 創(chuàng)建備份點
         status.createAndHoldSavepoint();
         return status;
      }
      else {
         // Nested transaction through nested begin and commit/rollback calls.
         // Usually only for JTA: Spring synchronization might get activated here
         // in case of a pre-existing JTA transaction.
         boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
         DefaultTransactionStatus status = newTransactionStatus(
               definition, transaction, true, newSynchronization, debugEnabled, null);
         // 不支持備份點的情況下會新建事務
         doBegin(transaction, definition);
         prepareSynchronization(status, definition);
         return status;
      }
   }
 
   // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
   if (debugEnabled) {
      logger.debug("Participating in existing transaction");
   }
   if (isValidateExistingTransaction()) {
      if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
         Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
         if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
            Constants isoConstants = DefaultTransactionDefinition.constants;
            throw new IllegalTransactionStateException("Participating transaction with definition [" +
                  definition + "] specifies isolation level which is incompatible with existing transaction: " +
                  (currentIsolationLevel != null ?
                        isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
                        "(unknown)"));
         }
      }
      if (!definition.isReadOnly()) {
         if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
            throw new IllegalTransactionStateException("Participating transaction with definition [" +
                  definition + "] is not marked as read-only but existing transaction is");
         }
      }
   }
   boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
   return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}

2.1 一些干貨

2.1.1 aop注入的實現(xiàn)過程

doCreateBean中會暴露一個bean引用,用以處理循環(huán)引用;同時大家熟知的AOP就是通過getEarlyBeanReference(..)方法植入的;具體的,是在wrapIfNecessary(..) 方法中封裝了advice并創(chuàng)建了代理;

image.png

image.png

2.1.2 @Autowired注解的實現(xiàn)

image.png

doCreateBean(..)中的populateBean(..)方法,實現(xiàn)了基于@Autowired注解的實現(xiàn),根據(jù)名稱或類型進行依賴的注入;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容