spring 源码之 @Autowired @Value 是怎么实现的

407 阅读6分钟

常用的@Autowired

这个估计是使用spring最常用的注解了,往一个bean添加依赖,作用应该众所周知

@Value

@Value 一般用作配置类,比如:

   @Value("${file.server.host}")
    private String basicHost;

AutowiredAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessor 是解析这两个注解的关键

 * @see Autowired
 * @see Value
 */
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
		implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
		}

可以看到这个类,继承了InstantiationAwareBeanPostProcessorAdapter实现了父类方法postProcessProperties。并且实现了MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition。这两个bean后置处理器再bean实例化,初始化过程都有有作用的,详情请见 juejin.cn/post/684790…

AutowiredAnnotationBeanPostProcessor实例化做了什么

	public AutowiredAnnotationBeanPostProcessor() {
		this.autowiredAnnotationTypes.add(Autowired.class);
		this.autowiredAnnotationTypes.add(Value.class);
 .......省略添加 @Inject 的方法
	}

实例化的时候往 autowiredAnnotationTypes 这个set集合放入 Autowired 和value这两个classs。

AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition

	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
	//重要方法,往下走
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
//......校验获取缓存key,省略
//从缓存中获取 InjectionMetadata
		InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
		if (InjectionMetadata.needsRefresh(metadata, clazz)) {
		//重复校验,从缓存取,省略
		//重要,往下走就会解析
					metadata = buildAutowiringMetadata(clazz);
		//将获取到的metadata放到缓存中,让下次的后置处理器来取(postProcessProperties)			
					this.injectionMetadataCache.put(cacheKey, metadata);
				}
			}
		}
		return metadata;
	}
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
		List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
		Class<?> targetClass = clazz;

		do {
			final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
//对属性的解析 遍历 autowiredAnnotationTypes(初始化的时候塞了三个注解进去)
//看是否这个类的属性有这三个注解,如果有就放到List中缓存下来
			ReflectionUtils.doWithLocalFields(targetClass, field -> {
			//找属性是否有@Autowired @Value @Inject
				AnnotationAttributes ann = findAutowiredAnnotation(field);
				if (ann != null) {
				//判断注解的 require 属性
					boolean required = determineRequiredStatus(ann);
					currElements.add(new AutowiredFieldElement(field, required));
				}
			});
//.....上面是对属性的解析,下面是对方法的解析方法也可以@Autowire等注解
//大概意思差不多就省略,只是两个解析后的结果封装的对象不同
//属性:AutowiredFieldElement 方法:AutowiredMethodElement  
//都是继承  InjectionMetadata.InjectedElement
			 
		}
		while (targetClass != null && targetClass != Object.class);
//将解析完之后的elements(List) 放到 InjectionMetadata对象中,然后缓存到map中
		return new InjectionMetadata(clazz, elements);
	}

将解析出来之后的数据放到缓存之后,肯定有人取get缓存然后处理,如果了解bean的初始化就知道是哪个类的哪个方法去取这个缓存来解析的

AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues

这个方法也在spring的后置处理器中讲过了,主要是往bean中填充属性等等

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//调用上面的findAutowiringMetadata这个方法
//这个方法刚才也看了,一进去就会往缓存中取数据
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
		//调用inject,往下看inject做了什么
			metadata.inject(bean, beanName, pvs);
		}
		return pvs;
	}
	public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//............
//循环injectedElements 这个就是刚才解析完放到缓存的List
			for (InjectedElement element : elementsToIterate) {
			//往下看inject做了什么
				element.inject(target, beanName, pvs);
			}
		}
	}

以属性的解析为例

	@Override
		protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
        //获取需要注入的属性
			Field field = (Field) this.member;
			Object value;
            //如果有缓存,就从缓存中拿,这个主要应用在原型模式
            //原型模型,每次都要生产bean,每次都要重新注入依赖
            //所以如果有缓存,就少了解析的过程
			if (this.cached) {
				value = resolvedCachedArgument(beanName, this.cachedFieldValue);
			}
			else {
            //构造依赖的实体类 DependencyDescriptor
				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())) {
                                        // 通过 ShortcutDependencyDescriptor 来缓存
									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);
			}
		}
	}
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

		descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
        //判断依赖是否 optional 类型
		if (Optional.class == descriptor.getDependencyType()) {
			return createOptionalDependency(descriptor, requestingBeanName);
		}
        //判断依赖是否 是objectFactory 类型
		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;
		}
	}
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();
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
			if (value != null) {
				if (value instanceof String) {
					String strVal = resolveEmbeddedValue((String) value);
					BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
					value = evaluateBeanDefinitionString(strVal, bd);
				}
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				return (descriptor.getField() != null ?
						converter.convertIfNecessary(value, type, descriptor.getField()) :
						converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
			}
//对集合数组的处理,所以,可以注入一个 list 或者 map 等集合数组
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}
//通过依赖类型去容器中找
			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) {
            //通过名称去匹配
				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
				if (autowiredBeanName == null) {
					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;
					}
				}
                //匹配到合适的名称
				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);
			}
            //找到的一定是已经实例化的对象,有可能是 class
            //如果是class 就通过 beanFactory.getBean 去实例化一个bean
			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);
		}
	}
protected Map<String, Object> findAutowireCandidates(
			@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
//通过类型去容器中bean名称
		String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
				this, requiredType, true, descriptor.isEager());
		Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
        //从依赖的缓存中获取
		for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
			Class<?> autowiringType = classObjectEntry.getKey();
			if (autowiringType.isAssignableFrom(requiredType)) {
				Object autowiringValue = classObjectEntry.getValue();
				autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
				if (requiredType.isInstance(autowiringValue)) {
					result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
					break;
				}
			}
		}
        //遍历所有的符合注入类型的名称
        //通过名称取获取bean的calss或者bean对象
        //放到resutl
		for (String candidate : candidateNames) {
			if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
				addCandidateEntry(result, candidate, descriptor, requiredType);
			}
		}
		if (result.isEmpty()) {
			boolean multiple = indicatesMultipleBeans(requiredType);
			// Consider fallback matches if the first pass failed to find anything...
			DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
			for (String candidate : candidateNames) {
				if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
						(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
					addCandidateEntry(result, candidate, descriptor, requiredType);
				}
			}
			if (result.isEmpty() && !multiple) {
				// Consider self references as a final pass...
				// but in the case of a dependency collection, not the very same bean itself.
				for (String candidate : candidateNames) {
					if (isSelfReference(beanName, candidate) &&
							(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
							isAutowireCandidate(candidate, fallbackDescriptor)) {
						addCandidateEntry(result, candidate, descriptor, requiredType);
					}
				}
			}
		}
		return result;
	}


过程:

  • 1.对于原型模型的对象,会对需要注入的信息做缓存
  • 2.DefaultListableBeanFactory#resolveDependency:解决依赖
  • 3.DefaultListableBeanFactory#doResolveDependency:真正处理依赖,会判断能不能从缓存中获取依赖,如果可以直接返回。一般只有原型才有缓存,如果缓存没有就开始解析依赖。先通过resolveMultipleBeans去判断是否是集合数组,如果是,就通过findAutowireCandidates寻找需要依赖的,如果不是集合框架,也是通过findAutowireCandidates寻找依赖,寻找依赖的时候是通过Class类型去找名称,通过名称去找实体类或者是class,找到之后返回去,但是如果找到多个就通过determineAutowireCandidate来判断需要注入那个,主要是通过属性名称跟bean名称来匹配,如果匹配不到合适的就报错,如果找到的时候对象直接注入,如果找到的是class就通过beanFactory.getBean 去容器中实例化bean
  • 4.所以@Autowired 是通过class 去找bean名称,在通过bean名称去容器中拿,如果拿到多个就通过属性名称去匹配。

总结

AutowiredAnnotationBeanPostProcessor 主要是解决@Autowired 和 @Value注解的关键, AutowiredAnnotationBeanPostProcessor 实现了 MergedBeanDefinitionPostProcessor继承了InstantiationAwareBeanPostProcessorAdapter这两个,再bean的实例化过程分别先后被调用相应的方法 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 是先调用解析出需要依赖注入的属性,放到缓存中。 InstantiationAwareBeanPostProcessorAdapte#postProcessProperties 后执行,这是后缓存中已经有了需要依赖注入的属性集合,直接拿,然后解析,最终通过bean工厂的getBean方法从spring容器中获取依赖,调用反射注入进去。