Spring中@Autowired与@Resource自动注入实现原理

关联博文
Spring后置处理器中的InstantiationAwareBeanPostProcessor详解
Spring中Bean实例化过程中的initializeBean方法
Spring中Bean实例化过程中的populateBean方法
Spring中@Autowired与@Resource自动注入实现原理
Spring中如何获取到一个Bean实例?

从autowiring使用上可以知道,这个autowiring属性在对Bean属性进行依赖注入时起作用。而这是在populateBean中实现的。也就是说,对属性autowiring的处理是populateBean的一部分。在前面我们分析Spring中Bean实例化过程中的populateBean方法可以看到自动注入的解析出现在两个部分。

第一部分:

// AbstractAutowireCapableBeanFactory#populateBean
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
	MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
	// Add property values based on autowire by name if applicable.
	if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
		autowireByName(beanName, mbd, bw, newPvs);
	}
	// Add property values based on autowire by type if applicable.
	if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
		autowireByType(beanName, mbd, bw, newPvs);
	}
	pvs = newPvs;
}

第二部分:

InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);

在第一部分为解析自动注入标识resolvedAutowireMode,默认值为AutowireCapableBeanFactory.AUTOWIRE_NO也就是0。当其为0时,不会执行autowireByName或者autowireByType逻辑。

postProcessProperties则可以理解为一种补偿机制,比如AutowiredAnnotationBeanPostProcessor的该方法,会尝试解析@Autowired注解触发依赖Bean的获取过程。

接下来我们从源码角度分析这两部分的流程。

【1】autowireByName和autowireByType

① autowireByName

当resolvedAutowireMode为1时,即AUTOWIRE_BY_NAME将会触发autowireByName(beanName, mbd, bw, newPvs);

方法源码如下:

//AbstractAutowireCapableBeanFactory#autowireByName
protected void autowireByName(
		String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

// 获取未满足的非简单类型的属性名称
	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
	for (String propertyName : propertyNames) {
	// 如果当前容器包含该属性名称对应的bean
		if (containsBean(propertyName)) {
		// 触发Bean的获取
			Object bean = getBean(propertyName);
			//更新pvs
			pvs.add(propertyName, bean);

			// 注册记录beanName与依赖 bean名称
			registerDependentBean(propertyName, beanName);
			if (logger.isTraceEnabled()) {
				logger.trace("Added autowiring by name from bean name '" + beanName +
						"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
			}
		}
		else {
			if (logger.isTraceEnabled()) {
				logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
						"' by name: no matching bean found");
			}
		}
	}
}

方法如上所示,获取需要解析的依赖bean。遍历循环尝试从容器中获取bean,然后更新到pvs中。最后调用registerDependentBean方法进行beanName与依赖bean名称留存记录。

② registerDependentBean

registerDependentBean方法如下所示,其使用dependentBeanMapdependenciesForBeanMap记录了beanName都被依赖了哪些bean和dependentBeanName都依赖了哪些bean。

public void registerDependentBean(String beanName, String dependentBeanName) {
	String canonicalName = canonicalName(beanName);

	synchronized (this.dependentBeanMap) {
		Set<String> dependentBeans =
				this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
		if (!dependentBeans.add(dependentBeanName)) {
			return;
		}
	}

	synchronized (this.dependenciesForBeanMap) {
		Set<String> dependenciesForBean =
				this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
		dependenciesForBean.add(canonicalName);
	}
}

在DefaultSingletonBeanRegistry中维护了一系列final map。其中dependentBeanMap 表示 beanName---哪些bean依赖了beanName,dependenciesForBeanMap 表示 beanName---beanName依赖了哪些bean

/** Map between dependent bean names: bean name to Set of dependent bean names. */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

/** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

③ autowireByType

// AbstractAutowireCapableBeanFactory#autowireByType
protected void autowireByType(
		String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

	TypeConverter converter = getCustomTypeConverter();
	if (converter == null) {
		converter = bw;
	}

	Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
	// 获取未满足的非简单类型的bean名称/属性名称,
	//如创建我们的XXXMapper时会解析sqlSessionFactory、sqlSessionTemplate
	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
	// 遍历循环解析
	for (String propertyName : propertyNames) {
		try {
			// 获取属性描述符
			PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
			// Don't try autowiring by type for type Object: never makes sense,
			// even if it technically is a unsatisfied, non-simple property.
			
			// 如果属性类型是Object,直接抛出异常
			if (Object.class != pd.getPropertyType()) {
			
				// 获取写方法参数对象,就是setXXXXX方法的参数对象
				MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
				// Do not allow eager init for type matching in case of a prioritized post-processor.
				
				// 判断是否为PriorityOrdered对象,即可以忽略order排序规则
				// 如果是PriorityOrdered则eager为false,否则为true。
				boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
				DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);

			// 核心方法,解析依赖
				Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);

		// 如果解析到依赖对象,比如sqlSessionFactory,那么放到pvs中
				if (autowiredArgument != null) {
					pvs.add(propertyName, autowiredArgument);
				}
				for (String autowiredBeanName : autowiredBeanNames) {

				//该方法前面提到过,注册记录bean与依赖bean的关系
					registerDependentBean(autowiredBeanName, beanName);
					if (logger.isTraceEnabled()) {
						logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
								propertyName + "' to bean named '" + autowiredBeanName + "'");
					}
				}
				autowiredBeanNames.clear();
			}
		}
		catch (BeansException ex) {
			throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
		}
	}
}

PropertyDescriptor 属性描述符。其包括属性名称、读方法、写方法、属性类型等。

MethodParameter,方法参数类型。其包括方法调用类、所属类、参数类型、参数个数、方法名称、方法返回类型、参数注解、异常类型等等。

如上代码所示,这里会解析得到propertyNames然后遍历解析依赖,之后会同autowireByName一样调用registerDependentBean方法注册记录bean与依赖bean的关系。

那么如何解析依赖呢?我们继续往下看。

④ 依赖解析resolveDependency

继续分析autowireByType,这部分我们分析依赖如何解析的。如下是DefaultListableBeanFactoryresolveDependency方法,这也是依赖解析的核心方法。在下文AutowiredAnnotationBeanPostProcessor的inject同样流转到了该方法。

public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
		@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

// 默认是DefaultParameterNameDiscoverer,在分析springmvc流程中我们也提到过
	descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());

// 判断依赖类型,通常这里是parameterType
	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 {
	// 这里是核心入口,这里是ContextAnnotationAutowireCandidateResolver
	// 判断是否为Lazy,如果是则使用ProxyFactory创建代理
		Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
				descriptor, requestingBeanName);
		if (result == null) {
		// 如果非Lazy,则进入实际依赖解析过程
			result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
		}
		return result;
	}
}

如上代码所示,首先设置ParameterNameDiscoverer,默认是DefaultParameterNameDiscoverer。然后判断依赖类型,根据依赖类型进行不同的处理。其中在最后一部分中会判断是否为Lazy,如果是Lazy则使用ProxyFactory创建代理返回。如果不是Lazy则进入实际依赖解析过程。

Lazy时,创建代理的过程可以参考方法ContextAnnotationAutowireCandidateResolver的buildLazyResolutionProxy方法。

关于AutowireCandidateResolver

如下所示,DefaultListableBeanFactory内部维护了该成员默认是SimpleAutowireCandidateResolver。

private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();

但是在AnnotationConfigUtilsregisterAnnotationConfigProcessors方法中会为容器设置解析器为ContextAnnotationAutowireCandidateResolver,这整个候选解析器是QualifierAnnotationAutowireCandidateResolver的子类。

我们继续看public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException 方法,这是实际解析依赖的入口。

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;
		}
//获取依赖类型,比如interface org.apache.ibatis.session.SqlSessionFactory
		Class<?> type = descriptor.getDependencyType();

	// 这部分处理 @Value 注解
	// value如${com.jane.file.baseFilePath}
		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());
			try {
				return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
			}
			catch (UnsupportedOperationException ex) {
				// A custom TypeConverter which does not support TypeDescriptor resolution...
				return (descriptor.getField() != null ?
						converter.convertIfNecessary(value, type, descriptor.getField()) :
						converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
			}
		}

// 处理集合类型,比如Array Map Collection
		Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
		if (multipleBeans != null) {
			return multipleBeans;
		}

// 得到候选的、匹配的bean class实例:beanName---bean class 对象
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
		if (matchingBeans.isEmpty()) {
		// 如果为空且required,则抛出异常NoSuchBeanDefinitionException
			if (isRequired(descriptor)) {
				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
			}
			return null;
		}

		String autowiredBeanName;
		Object instanceCandidate;

		if (matchingBeans.size() > 1) {
		// 如果有多个,则根据@Primary和@Priority进行抉择
			autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
			if (autowiredBeanName == null) {
			
			 //如果抉择不出,则可能抛出异常NoUniqueBeanDefinitionException
				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();
			// 解析得到的依赖bean名称
			autowiredBeanName = entry.getKey();
			// 解析得到的依赖bean实例-Class对象哦,还需要进一步解析
			instanceCandidate = entry.getValue();
		}

		if (autowiredBeanNames != null) {
		// 放入autowiredBeanNames,如sqlSessionFactory
			autowiredBeanNames.add(autowiredBeanName);
		}
		// 如果实例是Class对象,则解析为真实的Bean实例对象
		if (instanceCandidate instanceof Class) {
		
			// beanFactory.getBean(beanName); 也就是getBean的过程
			instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
		}
		Object result = instanceCandidate;
		if (result instanceof NullBean) {
			if (isRequired(descriptor)) {
			// 抛出NoSuchBeanDefinitionException
				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
			}
			result = null;
		}
		if (!ClassUtils.isAssignableValue(type, result)) {
		// 抛出BeanNotOfRequiredTypeException
			throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
		}
		return result;
	}
	finally {
		ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
	}
}

如上代码所示,这里可以总结为三个核心方法:

  • resolveMultipleBeans,处理集合类型,如Array、Map、Collection;
  • findAutowireCandidates,处理单个对象
  • descriptor.resolveCandidate(autowiredBeanName, type, this);,将Class对象解析为真实的bean实例,这里会触发getBean的过程。可以说真正的依赖解析是在这里实行的。

⑤ @Value

在上面方法中可以看到如下代码,其实就是对@Value注解做了处理。

Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);

如下所示,AbstractBeanFactoryresolveEmbeddedValue方法会尝试使用StringValueResolver解析得到实际的Value值,比如本文这里的D://myfilemapping/bookrecommend/file
在这里插入图片描述

【2】postProcessProperties

这里指的是InstantiationAwareBeanPostProcessorpostProcessProperties。前面我们提到过,如果resolvedAutowireMode为0,那么是不会执行autowireByName或者autowireByType的逻辑的。此时@Autowired、@Resource注解就由postProcessProperties方法提供实习。

AutowiredAnnotationBeanPostProcessor处理@Autowired,CommonAnnotationBeanPostProcessor处理@Resource。

如下所示是AutowiredAnnotationBeanPostProcessor的postProcessProperties方法,该方法首先获取到需要依赖注入的元素,然后调用注入方法得到实例对象。

@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 获取需要依赖注入的元素
	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;
}

① 获取依赖注入的元素

如下所示AutowiredAnnotationBeanPostProcessorfindAutowiringMetadata方法找到那些标注了@Autowired注解的字段和方法,提取出来需要进行依赖解析的元素。

private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
	// Fall back to class name as cache key, for backwards compatibility with custom callers.
	String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
	// Quick check on the concurrent map first, with minimal locking.
	InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
	if (InjectionMetadata.needsRefresh(metadata, clazz)) {
		synchronized (this.injectionMetadataCache) {
			metadata = this.injectionMetadataCache.get(cacheKey);
			if (InjectionMetadata.needsRefresh(metadata, clazz)) {
				if (metadata != null) {
					metadata.clear(pvs);
				}
				metadata = buildAutowiringMetadata(clazz);
				this.injectionMetadataCache.put(cacheKey, metadata);
			}
		}
	}
	return metadata;
}


private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
	if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
		return InjectionMetadata.EMPTY;
	}

	List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
	Class<?> targetClass = clazz;

	do {
		final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

		ReflectionUtils.doWithLocalFields(targetClass, field -> {
			MergedAnnotation<?> ann = findAutowiredAnnotation(field);
			if (ann != null) {
				if (Modifier.isStatic(field.getModifiers())) {
					if (logger.isInfoEnabled()) {
						logger.info("Autowired annotation is not supported on static fields: " + field);
					}
					return;
				}
				boolean required = determineRequiredStatus(ann);
				currElements.add(new AutowiredFieldElement(field, required));
			}
		});

		ReflectionUtils.doWithLocalMethods(targetClass, method -> {
			Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
			if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
				return;
			}
			MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
			if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
				if (Modifier.isStatic(method.getModifiers())) {
					if (logger.isInfoEnabled()) {
						logger.info("Autowired annotation is not supported on static methods: " + method);
					}
					return;
				}
				if (method.getParameterCount() == 0) {
					if (logger.isInfoEnabled()) {
						logger.info("Autowired annotation should only be used on methods with parameters: " +
								method);
					}
				}
				boolean required = determineRequiredStatus(ann);
				PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
				currElements.add(new AutowiredMethodElement(method, required, pd));
			}
		});

		elements.addAll(0, currElements);
		targetClass = targetClass.getSuperclass();
	}
	while (targetClass != null && targetClass != Object.class);

	return InjectionMetadata.forElements(elements, clazz);
}

② 依赖注入对象解析

接下来我们再看一下注入过程

// InjectionMetadata#inject
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
	Collection<InjectedElement> checkedElements = this.checkedElements;
	Collection<InjectedElement> elementsToIterate =
			(checkedElements != null ? checkedElements : this.injectedElements);
	if (!elementsToIterate.isEmpty()) {
	// 遍历每一个元素,触发注入过程
		for (InjectedElement element : elementsToIterate) {
			if (logger.isTraceEnabled()) {
				logger.trace("Processing injected element of bean '" + beanName + "': " + element);
			}
			element.inject(target, beanName, pvs);
		}
	}
}

// AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
@Override
	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 {
			// 这里是核心,解析依赖
				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与依赖bean的关系
						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;
				}
			}
		}
		// 如果value不为null,则为filed赋值value
		if (value != null) {
			ReflectionUtils.makeAccessible(field);
			field.set(bean, value);
		}
	}
}

如上代码所示,这里核心逻辑就是 beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);其将会触发依赖解析过程也就是【1】中的第③部分。

③ @Resource

当你controller有@Resource注解时,CommonAnnotationBeanPostProcessor的postProcessProperties方法就会去解析并注入。

@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
	InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
	try {
		metadata.inject(bean, beanName, pvs);
	}
	catch (Throwable ex) {
		throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
	}
	return pvs;
}

private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) {
	// Fall back to class name as cache key, for backwards compatibility with custom callers.
	String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
	// Quick check on the concurrent map first, with minimal locking.
	// 首先从缓存里面查找
	InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
	// metadata == null || metadata.targetClass != clazz
	if (InjectionMetadata.needsRefresh(metadata, clazz)) {
	// 加锁--双重校验锁
		synchronized (this.injectionMetadataCache) {
		//再次从缓存获取
			metadata = this.injectionMetadataCache.get(cacheKey);
			// 再次进行判断
			if (InjectionMetadata.needsRefresh(metadata, clazz)) {
				if (metadata != null) {
					metadata.clear(pvs);
				}
				// 核心在这里,根据Bean类型获取其需要处理的@Resource元素
				metadata = buildResourceMetadata(clazz);
				// 放入缓存
				this.injectionMetadataCache.put(cacheKey, metadata);
			}
		}
	}
	return metadata;
}

我们看下其收集元素的方法,这里将会收集目标元素如WebServiceRefElement(@WebServiceRef)EjbRefElement(@EJB)及我们常用的ResourceElement(@Resource)

private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
	if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {
		return InjectionMetadata.EMPTY;
	}

	List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
	Class<?> targetClass = clazz;

	do {
		final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

// 从field字段级别收集
		ReflectionUtils.doWithLocalFields(targetClass, field -> {
			if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
				if (Modifier.isStatic(field.getModifiers())) {
					throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
				}
				currElements.add(new WebServiceRefElement(field, field, null));
			}
			else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) {
				if (Modifier.isStatic(field.getModifiers())) {
					throw new IllegalStateException("@EJB annotation is not supported on static fields");
				}
				currElements.add(new EjbRefElement(field, field, null));
			}
			else if (field.isAnnotationPresent(Resource.class)) {
				if (Modifier.isStatic(field.getModifiers())) {
					throw new IllegalStateException("@Resource annotation is not supported on static fields");
				}
				if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
					currElements.add(new ResourceElement(field, field, null));
				}
			}
		});

// 从方法级别收集
		ReflectionUtils.doWithLocalMethods(targetClass, method -> {
			Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
			if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
				return;
			}
			if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
				if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) {
					if (Modifier.isStatic(method.getModifiers())) {
						throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
					}
					if (method.getParameterCount() != 1) {
						throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
					}
					PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
					currElements.add(new WebServiceRefElement(method, bridgedMethod, pd));
				}
				else if (ejbRefClass != null && bridgedMethod.isAnnotationPresent(ejbRefClass)) {
					if (Modifier.isStatic(method.getModifiers())) {
						throw new IllegalStateException("@EJB annotation is not supported on static methods");
					}
					if (method.getParameterCount() != 1) {
						throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
					}
					PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
					currElements.add(new EjbRefElement(method, bridgedMethod, pd));
				}
				else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
					if (Modifier.isStatic(method.getModifiers())) {
						throw new IllegalStateException("@Resource annotation is not supported on static methods");
					}
					Class<?>[] paramTypes = method.getParameterTypes();
					if (paramTypes.length != 1) {
						throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
					}
					if (!this.ignoredResourceTypes.contains(paramTypes[0].getName())) {
						PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
						currElements.add(new ResourceElement(method, bridgedMethod, pd));
					}
				}
			}
		});

		elements.addAll(0, currElements);
		targetClass = targetClass.getSuperclass();
	}
	while (targetClass != null && targetClass != Object.class);

	return InjectionMetadata.forElements(elements, clazz);
}

在这里插入图片描述
获取到目标元素后(比如我们@Resource注解的对象),其将会通过如下方法调用栈进行依赖的解析。

// 方法调用栈
InjectionMetadata#inject ->
InjectionMetadata.InjectedElement#inject ->
CommonAnnotationBeanPostProcessor.ResourceElement#getResourceToInject ->
CommonAnnotationBeanPostProcessor#getResource ->
CommonAnnotationBeanPostProcessor#autowireResource ->
DefaultListableBeanFactory#resolveDependency

这里我们最后可以看到,其同样走到了DefaultListableBeanFactorydresolveDependency方法,不再赘述。

需要注意一点的是,同@Autowired解析依赖的过程一样,这里也实现了lazyLookup 兼容。如果lazyLookup 为true,则创建代理,不触发实际对象解析。

// CommonAnnotationBeanPostProcessor.ResourceElement#getResourceToInject
@Override
protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
	return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
			getResource(this, requestingBeanName));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流烟默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值