1. 程式人生 > 其它 >Spring原始碼 18 IOC getBean

Spring原始碼 18 IOC getBean

前面實現了 ClassPathXmlApplicationContext 的構造,接下來分析其呼叫的 getBean 方法。
getBean(UserDao.class) 為例。

1 AbstractApplicationContext

public <T> T getBean(Class<T> requiredType) throws BeansException {
    // 斷言 Bean 工廠活動
    assertBeanFactoryActive();
    // 獲取 Bean 工廠
    // 獲取 Bean
    return getBeanFactory().getBean(requiredType);
}

1-1 斷言 Bean 工廠活動

assertBeanFactoryActive()
protected void assertBeanFactoryActive() {
   if (!this.active.get()) {
      if (this.closed.get()) {
         // 獲取顯示名稱
         throw new IllegalStateException(getDisplayName() + " has been closed already");
      }
      else {
         // 獲取顯示名稱
         throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
      }
   }
}

獲取顯示名稱前面已經分析過了,這裡不再分析。

1-1 獲取 Bean 工廠

getBeanFactory()

2 AbstractRefreshableApplicationContext

public final ConfigurableListableBeanFactory getBeanFactory() {
   DefaultListableBeanFactory beanFactory = this.beanFactory;
   if (beanFactory == null) {
      throw new IllegalStateException("BeanFactory not initialized or already closed - " + "call 'refresh' before accessing beans via the ApplicationContext");
   }
   return beanFactory;
}

if (beanFactory == null) 由於前面定義了 beanFactory,這裡直接返回。

1 AbstractApplicationContext

1-1 獲取 Bean

getBean(requiredType)

3 DefaultListableBeanFactory

public <T> T getBean(Class<T> requiredType) throws BeansException {
   // 獲取 Bean
   return getBean(requiredType, (Object[]) null);
}
public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {
   Assert.notNull(requiredType, "Required type must not be null");
   // 解析 Bean
   Object resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false);
   if (resolved == null) {
      throw new NoSuchBeanDefinitionException(requiredType);
   }
   return (T) resolved;
}

3-1 解析 Bean

resolveBean(ResolvableType.forRawClass(requiredType), args, false)
private <T> T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) {
    // 解析 Bean 命名
    NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull);
    if (namedBean != null) {
        return namedBean.getBeanInstance();
    }
    // 獲取父級 Bean 工廠
    BeanFactory parent = getParentBeanFactory();
    if (parent instanceof DefaultListableBeanFactory) {
        // 解析 Bean,遞迴呼叫
        return ((DefaultListableBeanFactory) parent).resolveBean(requiredType, args, nonUniqueAsNull);
    }
    else if (parent != null) {
        ObjectProvider<T> parentProvider = parent.getBeanProvider(requiredType);
        if (args != null) {
            return parentProvider.getObject(args);
        }
        else {
            return (nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable());
        }
    }
    return null;
}

3-2 解析 Bean 命名

resolveNamedBean(requiredType, args, nonUniqueAsNull)
private <T> NamedBeanHolder<T> resolveNamedBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException {
   Assert.notNull(requiredType, "Required type must not be null");
   // 獲取型別的 Bean 名稱
   String[] candidateNames = getBeanNamesForType(requiredType);
   if (candidateNames.length > 1) {
      List<String> autowireCandidates = new ArrayList<>(candidateNames.length);
      for (String beanName : candidateNames) {
         if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
            autowireCandidates.add(beanName);
         }
      }
      if (!autowireCandidates.isEmpty()) {
         candidateNames = StringUtils.toStringArray(autowireCandidates);
      }
   }
   if (candidateNames.length == 1) {
      // 解析 Bean 命名
      return resolveNamedBean(candidateNames[0], requiredType, args);
   } else if (candidateNames.length > 1) {
      Map<String, Object> candidates = CollectionUtils.newLinkedHashMap(candidateNames.length);
      for (String beanName : candidateNames) {
         if (containsSingleton(beanName) && args == null) {
            Object beanInstance = getBean(beanName);
            candidates.put(beanName, (beanInstance instanceof NullBean ? null : beanInstance));
         } else {
            candidates.put(beanName, getType(beanName));
         }
      }
      // 確定主要候選
      String candidateName = determinePrimaryCandidate(candidates, requiredType.toClass());
      if (candidateName == null) {
         // 確定最高優先順序候選
         candidateName = determineHighestPriorityCandidate(candidates, requiredType.toClass());
      }
      if (candidateName != null) {
         Object beanInstance = candidates.get(candidateName);
         if (beanInstance == null) {
            return null;
         }
         if (beanInstance instanceof Class) {
            // 解析 Bean 命名
            return resolveNamedBean(candidateName, requiredType, args);
         }
         return new NamedBeanHolder<>(candidateName, (T) beanInstance);
      }
      if (!nonUniqueAsNull) {
         throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet());
      }
   }
   return null;
}

3-3 確定主要候選

determinePrimaryCandidate(candidates, requiredType.toClass())
protected String determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType) {
   String primaryBeanName = null;
   for (Map.Entry<String, Object> entry : candidates.entrySet()) {
      String candidateBeanName = entry.getKey();
      Object beanInstance = entry.getValue();
      if (isPrimary(candidateBeanName, beanInstance)) {
         if (primaryBeanName != null) {
            boolean candidateLocal = containsBeanDefinition(candidateBeanName);
            boolean primaryLocal = containsBeanDefinition(primaryBeanName);
            if (candidateLocal && primaryLocal) {
               throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(), "more than one 'primary' bean found among candidates: " + candidates.keySet());
            } else if (candidateLocal) {
               primaryBeanName = candidateBeanName;
            }
         } else {
            primaryBeanName = candidateBeanName;
         }
      }
   }
   return primaryBeanName;
}

3-3 確定最高優先順序候選

determineHighestPriorityCandidate(candidates, requiredType.toClass())
protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) {
   String highestPriorityBeanName = null;
   Integer highestPriority = null;
   for (Map.Entry<String, Object> entry : candidates.entrySet()) {
      String candidateBeanName = entry.getKey();
      Object beanInstance = entry.getValue();
      if (beanInstance != null) {
         Integer candidatePriority = getPriority(beanInstance);
         if (candidatePriority != null) {
            if (highestPriorityBeanName != null) {
               if (candidatePriority.equals(highestPriority)) {
                  throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(), "Multiple beans found with the same priority ('" + highestPriority + "') among candidates: " + candidates.keySet());
               } else if (candidatePriority < highestPriority) {
                  highestPriorityBeanName = candidateBeanName;
                  highestPriority = candidatePriority;
               }
            } else {
               highestPriorityBeanName = candidateBeanName;
               highestPriority = candidatePriority;
            }
         }
      }
   }
   return highestPriorityBeanName;
}