从Spring源码角度看@Autowired(上篇)

从源码角度看@Autowired

@Autowired注解的源码

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {

	/**
	 * Declares whether the annotated dependency is required.
	 * <p>Defaults to {@code true}.
	 */
	boolean required() default true;

}
  • @Autowired只有一个属性 required,其默认值为true
  • 从@Target上看,其可以用在构造方法上、方法上、参数上、字段上、注解类型上
  • 从@Retention上看,其可以在运行期生效

处理@Autowired注解的后置处理器

  • 注:此处的后置处理器是将@Autowired修饰的属性或方法参数信息处理后赋值给RootBeanDefinition
  • AutowiredAnnotationBeanPostProcessor
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
	implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {}
  • 可以看到其实现了MergedBeanDefinitionPostProcessor

给@Autowired修饰的属性或方法上的参数赋值的后置处理器

  • CommonAnnotationBeanPostProcessor
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
	implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {}
  • 可以看到其实现了InstantiationAwareBeanPostProcessor

处理@Autowired的整个流程

上篇:将@Autowired修饰的属性和方法以InjectedElement形式添加到RootBeanDefinition中的externallyManagedConfigMembers属性中

org.springframework.beans.factory.support.RootBeanDefinition{
    Set<Member> externallyManagedConfigMembers;
}
1. 调用此后置处理器的入口

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors 这个方法会在bean实例化之后,属性未填充之前调用

// 这里AutowiredAnnotationBeanPostProcessor实现了MergedBeanDefinitionPostProcessor接口
// 所以将执行bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
	for (BeanPostProcessor bp : getBeanPostProcessors()) {
		if (bp instanceof MergedBeanDefinitionPostProcessor) {
			MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
			bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
		}
	}
}
// 这里的getBeanPostProcessor() 方法一共会获取7个[在没有自定义的BeanPostProcessor情况下],分别是
// 1. ApplicationContextAwareProcessor
// 2. ConfigurationClassPostProcessor$ImortAwareBeanPostProcessor
// 3. PostProcessorRegistrationDelegate$BeanPostProcessorChecker
// 4. CommonAnnotationBeanPostProcessor
// 5. AutowiredAnnotationBeanPostProcessor
// 6. RequiredAnnotationBeanPostProcessor
// 7. ApplicationListenerDetector
2. 执行postProcessMergedBeanDefinition方法

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    // 判断该bean的类型中是否有需要注入的元属性
	InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
	// 检查是否已注入
	metadata.checkConfigMembers(beanDefinition);
}
3. 执行findAutowiringMetadata方法获取类中的需要注入的元属性

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata

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.
	
	// 首先从injectionMetadataCache中获取该bean的需要注入的元数据信息
	// 如果获取不到则重新构建,这里利用了双检锁的方式判断是否需要needsRefresh
	// Map<String, InjectionMetadata> injectionMetadataCache; key为bean的名字,value为需要注入的元数据
	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;
}
4.构建需要注入的元数据

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
    // 存放所有需要注入的元数据列表
	List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
	Class<?> targetClass = clazz;

	do {
		final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
        // 判断目标类的属性上是否有@Autowired修饰的属性
		ReflectionUtils.doWithLocalFields(targetClass, field -> {
			AnnotationAttributes ann = findAutowiredAnnotation(field);
			if (ann != null) {
			    // 判断该字段的修饰符是否是static,如果是静态的则无法注入并打印日志
			    // field.getModifiers() 获取的就是类的修饰符,是一个int值,具体可百度此方法
				if (Modifier.isStatic(field.getModifiers())) {
					if (logger.isWarnEnabled()) {
						logger.warn("Autowired annotation is not supported on static fields: " + field);
					}
					return;
				}
				boolean required = determineRequiredStatus(ann);
				currElements.add(new AutowiredFieldElement(field, required));
			}
		});

        // 判断目标类的方法上是否有@Autowired修饰的方法
		ReflectionUtils.doWithLocalMethods(targetClass, method -> {
		    // 判断该方式是否是桥接方法
			Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
			if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
				return;
			}
			AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
			if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
			    // 判断方法是否是静态的,如果是静态的则无法注入且打印日志
				if (Modifier.isStatic(method.getModifiers())) {
					if (logger.isWarnEnabled()) {
						logger.warn("Autowired annotation is not supported on static methods: " + method);
					}
					return;
				}
				// 判断方法的参数是否是0个,如果是0个则也无法注入且打印日志
				if (method.getParameterCount() == 0) {
					if (logger.isWarnEnabled()) {
						logger.warn("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 new InjectionMetadata(clazz, elements);
}
4-0 获取Autowired注解的注解属性

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findAutowiredAnnotation

private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
	if (ao.getAnnotations().length > 0) {
	    // autowiredAnnotationTypes 是一个成员属性,用来存放可以解析的注解类型
	    // Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>();
		for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
			AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
			if (attributes != null) {
				return attributes;
			}
		}
	}
	return null;
}

// 下面的是可以解析的注解类型,可忽略
// 可以看到其在无参构造方法中增加了@Autowired、@Value注解,如果支持JSR-303的@Inject注解的话,也会将其加上
// @Value注解主要是用来获取properties、yaml、环境中的值,如"#{systemProperties.myProp}"
public AutowiredAnnotationBeanPostProcessor() {
	this.autowiredAnnotationTypes.add(Autowired.class);
	this.autowiredAnnotationTypes.add(Value.class);
	try {
		this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
				ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
		logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
	}
	catch (ClassNotFoundException ex) {
		// JSR-330 API not available - simply skip.
	}
}
4-1 ReflectionUtils.doWithLocalFields 对类中的所有属性做一些操作

org.springframework.util.ReflectionUtils#doWithLocalFields

public static void doWithLocalFields(Class<?> clazz, FieldCallback fc) {
	for (Field field : getDeclaredFields(clazz)) {
		try {
			fc.doWith(field);
		}
		catch (IllegalAccessException ex) {
			throw new IllegalStateException("Not allowed to access field '" + field.getName() + "': " + ex);
		}
	}
}

private static Field[] getDeclaredFields(Class<?> clazz) {
	Assert.notNull(clazz, "Class must not be null");
	// declaredFieldsCache 会以类为key,其所有的字段以数组方式作为value存储在map中
	// Map<Class<?>, Field[]> declaredFieldsCache = new ConcurrentReferenceHashMap(256);
	Field[] result = declaredFieldsCache.get(clazz);
	if (result == null) {
		try {
			result = clazz.getDeclaredFields();
			
			declaredFieldsCache.put(clazz, (result.length == 0 ? NO_FIELDS : result));
		}
		catch (Throwable ex) {
			throw new IllegalStateException("Failed to introspect Class [" + clazz.getName() +
					"] from ClassLoader [" + clazz.getClassLoader() + "]", ex);
		}
	}
	return result;
}
4-2 ReflectionUtils.doWithLocalMethods 对类中的方法做一些操作

org.springframework.util.ReflectionUtils#doWithLocalMethods

public static void doWithLocalMethods(Class<?> clazz, MethodCallback mc) {
	Method[] methods = getDeclaredMethods(clazz);
		for (Method method : methods) {
		try {
			mc.doWith(method);
		}
		catch (IllegalAccessException ex) {
			throw new IllegalStateException("Not allowed to access method '" + method.getName() + "': " + ex);
		}
	}
}

private static Method[] getDeclaredMethods(Class<?> clazz) {
	Assert.notNull(clazz, "Class must not be null");
	// declaredMethodsCache 会以类为key,其所有的方法以数组方式作为value存储在map中
	// Map<Class<?>, Method[]> declaredMethodsCache = new ConcurrentReferenceHashMap<>(256);
	Method[] result = declaredMethodsCache.get(clazz);
	if (result == null) {
		try {
			Method[] declaredMethods = clazz.getDeclaredMethods();
			List<Method> defaultMethods = findConcreteMethodsOnInterfaces(clazz);
			if (defaultMethods != null) {
				result = new Method[declaredMethods.length + defaultMethods.size()];
				System.arraycopy(declaredMethods, 0, result, 0, declaredMethods.length);
				int index = declaredMethods.length;
				for (Method defaultMethod : defaultMethods) {
					result[index] = defaultMethod;
					index++;
				}
			}
			else {
				result = declaredMethods;
			}
			declaredMethodsCache.put(clazz, (result.length == 0 ? NO_METHODS : result));
		}
		catch (Throwable ex) {
			throw new IllegalStateException("Failed to introspect Class [" + clazz.getName() +
					"] from ClassLoader [" + clazz.getClassLoader() + "]", ex);
		}
	}
	return result;
}

private static List<Method> findConcreteMethodsOnInterfaces(Class<?> clazz) {
	List<Method> result = null;
	for (Class<?> ifc : clazz.getInterfaces()) {
		for (Method ifcMethod : ifc.getMethods()) {
			if (!Modifier.isAbstract(ifcMethod.getModifiers())) {
				if (result == null) {
					result = new LinkedList<>();
				}
				result.add(ifcMethod);
			}
		}
	}
	return result;
}
4-3 BridgeMethodResolver.findBridgedMethod 判断是否是桥接方法

org.springframework.core.BridgeMethodResolver#findBridgedMethod
具体可参考 JAVA方法中Bridge修饰符,其主要是一个方法修饰符bridge,这个修饰符不是给程序员使用的,而是编译器为了实现泛型而自动产生的

public static Method findBridgedMethod(Method bridgeMethod) {
	if (!bridgeMethod.isBridge()) {
		return bridgeMethod;
	}

	// Gather all methods with matching name and parameter size.
	List<Method> candidateMethods = new ArrayList<>();
	Method[] methods = ReflectionUtils.getAllDeclaredMethods(bridgeMethod.getDeclaringClass());
	for (Method candidateMethod : methods) {
		if (isBridgedCandidateFor(candidateMethod, bridgeMethod)) {
			candidateMethods.add(candidateMethod);
		}
	}

	// Now perform simple quick check.
	if (candidateMethods.size() == 1) {
		return candidateMethods.get(0);
	}

	// Search for candidate match.
	Method bridgedMethod = searchCandidates(candidateMethods, bridgeMethod);
	if (bridgedMethod != null) {
		// Bridged method found...
		return bridgedMethod;
	}
	else {
		// A bridge method was passed in but we couldn't find the bridged method.
		// Let's proceed with the passed-in method and hope for the best...
		return bridgeMethod;
	}
}
  • 到此,已经收集完此类中所有需要注入的属性和方法,并存储于 InjectionMetadata
5. 执行checkConfigMembers完成BeanDefinition中的externallyManagedConfigMembers属性的注入

org.springframework.beans.factory.annotation.InjectionMetadata#checkConfigMembers

public void checkConfigMembers(RootBeanDefinition beanDefinition) {
	Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
	for (InjectedElement element : this.injectedElements) {
		Member member = element.getMember();
		if (!beanDefinition.isExternallyManagedConfigMember(member)) {
		    // 给RootBeanDefinition中添加额外配置
			beanDefinition.registerExternallyManagedConfigMember(member);
			checkedElements.add(element);
			if (logger.isDebugEnabled()) {
				logger.debug("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
			}
		}
	}
	this.checkedElements = checkedElements;
}
5-1 通过registerExternallyManagedConfigMember给RootBeanDefinition中注册额外配置

org.springframework.beans.factory.support.RootBeanDefinition#registerExternallyManagedConfigMember

public void registerExternallyManagedConfigMember(Member configMember) {
	synchronized (this.postProcessingLock) {
		if (this.externallyManagedConfigMembers == null) {
			this.externallyManagedConfigMembers = new HashSet<>(1);
		}
		this.externallyManagedConfigMembers.add(configMember);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

冰式的美式

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

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

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

打赏作者

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

抵扣说明:

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

余额充值