SpringBoot源码解析(七)@Primary
在SpringBoot中有许多类使用到了@Primary注解,关于用法,请看这篇博客:。
这次我们不说用法,从源码层面来看下:
一、入口
在创建bean的时候,我们会获取bean的依赖bean,这个方法就是DefaultListableBeanFactory的doResolveDependency方法,如果匹配的bean大于1,会执行如下方法:
if (matchingBeans.size() > 1) { autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
二、查找
最后会进入DefaultListableBeanFactory的如下方法,进行bean的过滤
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; }
isPrimary方法是判断是否有@Primary注解,如果有多个满足条件的bean有@Primary注解就会抛出异常:
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(), "more than one primary bean found among candidates: " + candidates.keySet());