从源码角度看@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);
}
}