可以看到,真正做事的方法是doResolveDependency
@Override public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { // descriptor代表当前需要注入的那个字段,或者方法的参数,也就是注入点 // ParameterNameDiscovery用于解析方法参数名称 descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); // 1. Optional<T> if (Optional.class == descriptor.getDependencyType()) { return createOptionalDependency(descriptor, requestingBeanName); // 2. ObjectFactory<T>、ObjectProvider<T> } else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) { return new DependencyObjectProvider(descriptor, requestingBeanName); // 3. javax.inject.Provider<T> } else if (javaxInjectProviderClass == descriptor.getDependencyType()) { return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName); } else { // 4. @Lazy Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( descriptor, requestingBeanName); // 5. 正常情况 if (result == null) { result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } return result; } } doResolveDependency public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { Object shortcut = descriptor.resolveShortcut(this); if (shortcut != null) { return shortcut; } // 依赖的具体类型 Class<?> type = descriptor.getDependencyType(); // 处理@Value注解,这里得到的时候@Value中的值 Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { if (value instanceof String) { // 解析@Value中的占位符 String strVal = resolveEmbeddedValue((String) value); // 获取到对应的bd BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); // 处理EL表达式 value = evaluateBeanDefinitionString(strVal, bd); } // 通过解析el表达式可能还需要进行类型转换 TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } // 对map,collection,数组类型的依赖进行处理 // 最终会根据集合中的元素类型,调用findAutowireCandidates方法 Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { return multipleBeans; } // 根据指定类型可能会找到多个bean // 这里返回的既有可能是对象,也有可能是对象的类型 // 这是因为到这里还不能明确的确定当前bean到底依赖的是哪一个bean // 所以如果只会返回这个依赖的类型以及对应名称,最后还需要调用getBean(beanName) // 去创建这个Bean 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; // 通过类型找到了多个 if (matchingBeans.size() > 1) { // 根据是否是主Bean // 是否是最高优先级的Bean // 是否是名称匹配的Bean // 来确定具体的需要注入的Bean的名称 // 到这里可以知道,Spring在查找依赖的时候遵循先类型再名称的原则(没有@Qualifier注解情况下) autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null) { // 无法推断出具体的名称 // 如果依赖是必须的,直接抛出异常 // 如果依赖不是必须的,但是这个依赖类型不是集合或者数组,那么也抛出异常 if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { return descriptor.resolveNotUnique(type, matchingBeans); } // 依赖不是必须的,但是依赖类型是集合或者数组,那么返回一个null else { return null; } } instanceCandidate = matchingBeans.get(autowiredBeanName); } else { // 直接找到了一个对应的Bean Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); autowiredBeanName = entry.getKey(); instanceCandidate = entry.getValue(); } if (autowiredBeanNames != null) { autowiredBeanNames.add(autowiredBeanName); } // 前面已经说过了,这里可能返回的是Bean的类型,所以需要进一步调用getBean if (instanceCandidate instanceof Class) { instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this); } // 做一些检查,如果依赖是必须的,查找出来的依赖是一个null,那么报错 // 查询处理的依赖类型不符合,也报错 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); } } findAutowireCandidates protected Map<String, Object> findAutowireCandidates( @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) { // 简单来说,这里就是到容器中查询requiredType类型的所有bean的名称的集合 // 这里会根据descriptor.isEager()来决定是否要匹配factoryBean类型的Bean // 如果isEager()为true,那么会匹配factoryBean,反之,不会 String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this, requiredType, true, descriptor.isEager()); Map<String, Object> result = new LinkedHashMap<>(candidateNames.length); // 第一步会到resolvableDependencies这个集合中查询是否已经存在了解析好的依赖 // 像我们之所以能够直接在Bean中注入applicationContext对象 // 就是因为Spring之前就将这个对象放入了resolvableDependencies集合中 for (Class<?> autowiringType : this.resolvableDependencies.keySet()) { if (autowiringType.isAssignableFrom(requiredType)) { Object autowiringValue = this.resolvableDependencies.get(autowiringType); // 如果resolvableDependencies放入的是一个ObjectFactory类型的依赖 // 那么在这里会生成一个代理对象 // 例如,我们可以在controller中直接注入request对象 // 就是因为,容器启动时就在resolvableDependencies放入了一个键值对 // 其中key为:Request.class,value为:ObjectFactory // 在实际注入时放入的是一个代理对象 autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); if (requiredType.isInstance(autowiringValue)) { // 这里放入的key不是Bean的名称 // value是实际依赖的对象 result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue); break; } } } // 接下来开始对之前查找出来的类型匹配的所有BeanName进行处理 for (String candidate : candidateNames) { // 不是自引用,什么是自引用? // 1.候选的Bean的名称跟需要进行注入的Bean名称相同,意味着,自己注入自己 // 2.或者候选的Bean对应的factoryBean的名称跟需要注入的Bean名称相同, // 也就是说A依赖了B但是B的创建又需要依赖A // 要符合注入的条件 if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { // 调用addCandidateEntry,加入到返回集合中,后文有对这个方法的分析 addCandidateEntry(result, candidate, descriptor, requiredType); } } // 排除自引用的情况下,没有找到一个合适的依赖 if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) { // 1.先走fallback逻辑,Spring提供的一个扩展吧,感觉没什么卵用 // 默认情况下fallback的依赖描述符就是自身 DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch(); for (String candidate : candidateNames) { if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } // fallback还是失败 if (result.isEmpty()) { // 处理自引用 // 从这里可以看出,自引用的优先级是很低的,只有在容器中真正的只有这个Bean能作为 // 候选者的时候,才会去处理,否则自引用是被排除掉的 for (String candidate : candidateNames) { if (isSelfReference(beanName, candidate) && // 不是一个集合或者 // 是一个集合,但是beanName跟candidate的factoryBeanName相同 (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) && isAutowireCandidate(candidate, fallbackDescriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } } } return result; } // candidates:就是findAutowireCandidates方法要返回的候选集合 // candidateName:当前的这个候选Bean的名称 // descriptor:依赖描述符 // requiredType:依赖的类型 private void addCandidateEntry(Map<String, Object> candidates, String candidateName, DependencyDescriptor descriptor, Class<?> requiredType) { // 如果依赖是一个集合,或者容器中已经包含这个单例了 // 那么直接调用getBean方法创建或者获取这个Bean if (descriptor instanceof MultiElementDescriptor || containsSingleton(candidateName)) { Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this); candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance)); } // 如果依赖的类型不是一个集合,这个时候还不能确定到底要使用哪个依赖, // 所以不能将这些Bean创建出来,所以这个时候,放入candidates是Bean的名称以及类型 else { candidates.put(candidateName, getType(candidateName)); } } 处理属性注入(@Autowired) postProcessProperties // 在applyMergedBeanDefinitionPostProcessors方法执行的时候, // 已经解析过了@Autowired注解(buildAutowiringMetadata方法) public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { // 这里获取到的是解析过的缓存好的注入元数据 InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { // 直接调用inject方法 // 存在两种InjectionMetadata // 1.AutowiredFieldElement // 2.AutowiredMethodElement // 分别对应字段的属性注入以及方法的属性注入 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; } 字段的属性注入 // 最终反射调用filed.set方法 protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Field field = (Field) this.member; 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 { // 这里可以看到,对@Autowired注解在字段上的处理 // 跟byType下自动注入的处理是一样的,就是调用resolveDependency方法 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; // 注册Bean之间的依赖关系 registerDependentBeans(beanName, autowiredBeanNames); // 如果这个类型的依赖只存在一个的话,我们就能确定这个Bean的名称 // 那么直接将这个名称缓存到ShortcutDependencyDescriptor中 // 第二次进行注入的时候就可以直接调用getBean(beanName)得到这个依赖了 // 实际上正常也只有一个,多个就报错了 // 另外这里会过滤掉@Vlaue得到的依赖 if (autowiredBeanNames.size() == 1) { String autowiredBeanName = autowiredBeanNames.iterator().next(); // 通过resolvableDependencies这个集合找的依赖不满足containsBean条件 // 不会进行缓存,因为缓存实际还是要调用getBean,而resolvableDependencies // 是没法通过getBean获取的 if (beanFactory.containsBean(autowiredBeanName) && beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { // 依赖描述符封装成ShortcutDependencyDescriptor进行缓存 this.cachedFieldValue = new ShortcutDependencyDescriptor( desc, autowiredBeanName, field.getType()); } } } else { this.cachedFieldValue = null; } this.cached = true; } } } if (value != null) { // 反射调用Field.set方法 ReflectionUtils.makeAccessible(field); field.set(bean, value); } } 方法的属性注入 // 代码看着很长,实际上逻辑跟字段注入基本一样 protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { // 判断XML中是否配置了这个属性,如果配置了直接跳过 // 换而言之,XML配置的属性优先级高于@Autowired注解 if (checkPropertySkipping(pvs)) { return; } Method method = (Method) this.member; Object[] arguments; if (this.cached) { arguments = resolveCachedArguments(beanName); } else { // 通过方法参数类型构造依赖描述符 // 逻辑基本一样的,最终也是调用beanFactory.resolveDependency方法 Class<?>[] paramTypes = method.getParameterTypes(); arguments = new Object[paramTypes.length]; DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length]; Set<String> autowiredBeans = new LinkedHashSet<>(paramTypes.length); Assert.state(beanFactory != null, "No BeanFactory available"); TypeConverter typeConverter = beanFactory.getTypeConverter(); // 遍历方法的每个参数 for (int i = 0; i < arguments.length; i++) { MethodParameter methodParam = new MethodParameter(method, i); DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required); currDesc.setContainingClass(bean.getClass()); descriptors[i] = currDesc; try { // 还是要调用这个方法 Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter); if (arg == null && !this.required) { arguments = null; break; } arguments[i] = arg; } catch (BeansException ex) { throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex); } } synchronized (this) { if (!this.cached) { if (arguments != null) { Object[] cachedMethodArguments = new Object[paramTypes.length]; System.arraycopy(descriptors, 0, cachedMethodArguments, 0, arguments.length); // 注册bean之间的依赖关系 registerDependentBeans(beanName, autowiredBeans); // 跟字段注入差不多,存在@Value注解,不进行缓存 if (autowiredBeans.size() == paramTypes.length) { Iterator<String> it = autowiredBeans.iterator(); for (int i = 0; i < paramTypes.length; i++) { String autowiredBeanName = it.next(); if (beanFactory.containsBean(autowiredBeanName) && beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) { cachedMethodArguments[i] = new ShortcutDependencyDescriptor( descriptors[i], autowiredBeanName, paramTypes[i]); } } } this.cachedMethodArguments = cachedMethodArguments; } else { this.cachedMethodArguments = null; } this.cached = true; } } } if (arguments != null) { try { // 反射调用方法 // 像我们的setter方法就是在这里调用的 ReflectionUtils.makeAccessible(method); method.invoke(bean, arguments); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } } 处理依赖检查 protected void checkDependencies( String beanName, AbstractBeanDefinition mbd, PropertyDescriptor[] pds, PropertyValues pvs) throws UnsatisfiedDependencyException { int dependencyCheck = mbd.getDependencyCheck(); for (PropertyDescriptor pd : pds) { // 有set方法但是在pvs中没有对应属性,那么需要判断这个属性是否要进行依赖检查 // 如果需要进行依赖检查的话,就需要报错了 // pvs中保存的是自动注入以及XML配置的属性 if (pd.getWriteMethod() != null && !pvs.contains(pd.getName())) { // 是否是基本属性,枚举/日期等也包括在内 boolean isSimple = BeanUtils.isSimpleProperty(pd.getPropertyType()); // 如果DEPENDENCY_CHECK_ALL,对任意属性都开启了依赖检查,报错 // DEPENDENCY_CHECK_SIMPLE,对基本属性开启了依赖检查并且是基本属性,报错 // DEPENDENCY_CHECK_OBJECTS,对非基本属性开启了依赖检查并且不是非基本属性,报错 boolean unsatisfied = (dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_ALL) || (isSimple && dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE) || (!isSimple && dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS); if (unsatisfied) { throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, pd.getName(), "Set this property value or disable dependency checking for this bean."); } } } } 将解析出来的属性应用到Bean上到这一步解析出来的属性主要有三个来源
XML中配置的
通过byName的方式自动注入的
通过byType的方式自动注入的