若是這是你第二次看到師長的文章,說明你在覬覦個人美色!O(∩_∩)O哈哈~java
點贊+關注再看,養成習慣spring
沒別的意思,就是須要你的窺屏^_^springboot
該趟專車是開往Spring Boot自動注入原理源碼分析的專車app
public interface PersonService { String hello(String name); }
@Service(value = "studentService") public class StudentServiceImpl implements PersonService { @Override public String hello(String name) { return "[student service] hello " + name; } }
@Service(value = "teacherService") public class TeacherServiceImpl implements PersonService { @Override public String hello(String name) { return "[teacher service] hello " + name; } }
@RestController public class TestController { @Autowired private PersonService studentService; @Autowired private PersonService teacherService; @GetMapping("/hello") public String hello(@RequestParam(name = "name") String name) { return studentService.hello(name) + "=======>" + teacherService.hello(name); } }
以上示例代碼很簡單,建立了一個接口,接口有兩個實現類,而後在控制器中注入實現類,從而完成業務方法的調用。接下來咱們就開始對源碼進行分析ide
在分析代碼以前咱們先回憶一下操做對象的步驟:源碼分析
有了上面的基礎知識,接下來就開始揭祕旅程post
在分析源碼的時候最關鍵的一步就是尋找程序的入口,有了入口咱們就成功了一半,那麼如何尋找程序的入口?針對此處的源碼分析,咱們能夠在TestController類上打一個斷點,而後查看調用鏈
基於調用鏈路,咱們看到有一個doCreateBean方法,該方法就是用來建立bean的,也就是咱們上面提到的實例化對象部分ui
AbstractAutowireCapableBeanFactory#doCreateBeanthis
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { // 建立bean instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); // ...省略部分代碼 // Initialize the bean instance. Object exposedObject = bean; try { // 填充bean,也就是咱們上面提到的調用對象的set方法設置對象屬性 populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); } // ...省略部分代碼 return exposedObject; }
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { // ...省略代碼 PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } // 遍歷全部的後置處理器 for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 經過斷點分析咱們能夠得知此處調用的是AutowiredAnnotationBeanPostProcessor#postProcessProperties PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } if (needsDepCheck) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); } }
AutowiredAnnotationBeanPostProcessor#postProcessProperties3d
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { // 查找當前bean須要注入的元數據信息,以TestController爲例,那麼須要注入的就是studentService和teacherService兩個屬性 InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { // 注入屬性 metadata.inject(bean, beanName, pvs); } catch (BeanCreationException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex); } return pvs; }
注入屬性 AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { // 獲取屬性,此處的屬性就是studentService Field field = (Field) this.member; // 屬性對應的value Object value; if (this.cached) { value = resolvedCachedArgument(beanName, this.cachedFieldValue); } else { DependencyDescriptor desc = new DependencyDescriptor(field, this.required); desc.setContainingClass(bean.getClass()); Set<String> autowiredBeanNames = new LinkedHashSet<>(1); Assert.state(beanFactory != null, "No BeanFactory available"); TypeConverter typeConverter = beanFactory.getTypeConverter(); try { // 解析屬性依賴 value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); } catch (BeansException ex) { throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex); } synchronized (this) { if (!this.cached) { if (value != null || this.required) { this.cachedFieldValue = desc; registerDependentBeans(beanName, autowiredBeanNames); if (autowiredBeanNames.size() == 1) { String autowiredBeanName = autowiredBeanNames.iterator().next(); if (beanFactory.containsBean(autowiredBeanName) && beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { this.cachedFieldValue = new ShortcutDependencyDescriptor( desc, autowiredBeanName, field.getType()); } } } else { this.cachedFieldValue = null; } this.cached = true; } } } if (value != null) { ReflectionUtils.makeAccessible(field); // 給屬性設置值,完成注入功能 field.set(bean, value); } }
解析屬性依賴 DefaultListableBeanFactory#resolveDependency
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); if (Optional.class == descriptor.getDependencyType()) { return createOptionalDependency(descriptor, requestingBeanName); } else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) { return new DependencyObjectProvider(descriptor, requestingBeanName); } else if (javaxInjectProviderClass == descriptor.getDependencyType()) { return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName); } else { Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( descriptor, requestingBeanName); if (result == null) { // 解析依賴 result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } return result; } }
解析屬性依賴 DefaultListableBeanFactory#doResolveDependency
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { // ...省略代碼 // 解析多個Bean,好比Array、List、Map類型,有興趣能夠本身查看分析 Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { return multipleBeans; } // 根據類型獲取候選對象,針對studentService而言,該屬性的類型爲PersonService // PersonService有2個實現類,StudentServiceImpl和TeacherServiceImpl // 因此此處獲取結果爲StudentServiceImpl對象和TeacherServiceImpl對象 Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null; } String autowiredBeanName; Object instanceCandidate; // 重點處理,若是存在多個匹配的bean if (matchingBeans.size() > 1) { // 從已經匹配的bean中選擇一個符合的bean autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null) { // 若是bean必須注入或者存在多個匹配的bean,則拋出異常 if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans); } else { // In case of an optional Collection/Map, silently ignore a non-unique case: // possibly it was meant to be an empty collection of multiple regular beans // (before 4.3 in particular when we didn't even look for collection beans). return null; } } // 根據bean名稱獲取對應的示例 instanceCandidate = matchingBeans.get(autowiredBeanName); } else { // We have exactly one match. Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); autowiredBeanName = entry.getKey(); instanceCandidate = entry.getValue(); } if (autowiredBeanNames != null) { autowiredBeanNames.add(autowiredBeanName); } if (instanceCandidate instanceof Class) { instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this); } Object result = instanceCandidate; if (result instanceof NullBean) { if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } result = null; } if (!ClassUtils.isAssignableValue(type, result)) { throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass()); } // 返回對應的示例對象 return result; } finally { ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); } }
此處主要根據類型獲取全部匹配的bean,若是匹配的bean有多個,那麼最後會選擇一個符合條件的bean名稱,而後將對應的bena實例返回,調用set方法進行進行注入,到此注入的原理本該結束了。可是仍是要分析一下Spring Boot是如何選擇出符合條件的bean?
選擇符合條件的bean DefaultListableBeanFactory#determineAutowireCandidate
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) { Class<?> requiredType = descriptor.getDependencyType(); // 若是bean對應的primary屬性爲true,則返回bean對應的名稱 String primaryCandidate = determinePrimaryCandidate(candidates, requiredType); if (primaryCandidate != null) { return primaryCandidate; } // 若是候選bean使用javax.annotation.Priority標註,返回高優先級bean對應的名稱 String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType); if (priorityCandidate != null) { return priorityCandidate; } // Fallback // 若是匹配bean的名稱和須要注入的屬性名稱一致,則返回匹配bean的名稱 for (Map.Entry<String, Object> entry : candidates.entrySet()) { String candidateName = entry.getKey(); Object beanInstance = entry.getValue(); if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) || matchesBeanName(candidateName, descriptor.getDependencyName())) { return candidateName; } } return null; }
獲取符合條件bean名稱總結:
回顧一下開頭的2個問題:
第一個問題:是在Bean實例化後,填充Bean的時候注入@Autowired標註的屬性
第二個問題:若是存在多個類型的Bean,會根據primary--->javax.annotation.Priority--->名稱依次過濾,獲得最終匹配的bean名稱