关注的是resolveNamedBean方法:
@SuppressWarnings("unchecked") @Nullable private <T> NamedBeanHolder<T> resolveNamedBean( ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException { Assert.notNull(requiredType, "Required type must not be null"); 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) { String beanName = candidateNames[0]; return new NamedBeanHolder<>(beanName, (T) getBean(beanName, requiredType.toClass(), args)); } else if (candidateNames.length > 1) { Map<String, Object> candidates = new LinkedHashMap<>(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 || beanInstance instanceof Class) { beanInstance = getBean(candidateName, requiredType.toClass(), args); } return new NamedBeanHolder<>(candidateName, (T) beanInstance); } if (!nonUniqueAsNull) { throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet()); } } return null; }
@SuppressWarnings("unchecked") @Nullable private <T> NamedBeanHolder<T> resolveNamedBean( ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException { Assert.notNull(requiredType, "Required type must not be null"); // 该方法根据传入的Class类型获取BeanName,因为有接口有多个实现类情况,所以这里返回是String数组。 // 调用getBean方法传入的type为com.javaedge.FactoryBeanService类型,但没有在Spring容器中注入FactoryBeanService类型的Bean // 所以讲道理在这里应该获取不到beanName,事实是这样吗?看对getBeanNamesForType的分析 String[] candidateNames = getBeanNamesForType(requiredType); // 有多个BeanName,则挑最合适的 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); } } // 如果只有一个BeanName,调用getBean获取Bean实例放到NamedBeanHolder // todo if (candidateNames.length == 1) { String beanName = candidateNames[0]; return new NamedBeanHolder<>(beanName, (T) getBean(beanName, requiredType.toClass(), args)); } // 经过挑选后,如果合适的BeanName还是多个 else if (candidateNames.length > 1) { Map<String, Object> candidates = new LinkedHashMap<>(candidateNames.length); for (String beanName : candidateNames) { // 看看是不是已经创建过的单例Bean if (containsSingleton(beanName) && args == null) { Object beanInstance = getBean(beanName); candidates.put(beanName, (beanInstance instanceof NullBean ? null : beanInstance)); } else { // 调用getType继续获取Bean实例 candidates.put(beanName, getType(beanName)); } } // 有多个Bean实例,则取带有Primary注解或者带有Primary信息的 String candidateName = determinePrimaryCandidate(candidates, requiredType.toClass()); if (candidateName == null) { // 如果没有Primary注解或者Primary相关的信息,则取优先级高的Bean candidateName = determineHighestPriorityCandidate(candidates, requiredType.toClass()); } if (candidateName != null) { Object beanInstance = candidates.get(candidateName); // Class类型的话 继续调用getBean获取Bean实例 if (beanInstance == null || beanInstance instanceof Class) { beanInstance = getBean(candidateName, requiredType.toClass(), args); } return new NamedBeanHolder<>(candidateName, (T) beanInstance); } if (!nonUniqueAsNull) { // 都没获取到,抛出异常 throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet()); } } return null; }
上面的代码中我们传入的type是com.javaedge.FactoryBeanService类型,但是在我们的Spring容器中却没有FactoryBeanService类型的Bean,那么我们是怎么从getBeanNamesForType获取到beanName的?
getBeanNamesForType