Spring的@Autowired原理

作为Spring自动注入相关的注解,@Autowired敢说第二,没其他注解敢说第一了。与JSR 330的@Inject和JSR-250的@Resource不同,这个注解是由Spring框架本身提供的。一般工作中,如果不是为了兼容问题,一般都是使用@Autowired。本文将从零讨论Spring中这个注解的原理。当然,也可以先参考本人另一篇博客:
Spring的@Resource原理 https://blog.csdn.net/m0_37607945/article/details/107434330
首先看一下这个注解的定义

package org.springframework.beans.factory.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Targ

@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;

}

这个注解是运行时起作用的(Retention),可以使用在构造方法、普通方法、方法参数、属性和注解类上面。比@Resource强悍的在于构造方法上也可以使用,甚至方法参数都可以,当然在普通方法上还可以是多个参数的方法,@Resource可以作用于方法,但是只能是单个参数的方法。另外还有注解类上面,也就是说这个注解可以构造复合注解。

首先来看一些使用的例子:

直接使用在构造方法上面

public class MovieRecommender {

    private final CustomerPreferenceDao customerPreferenceDao;

    @Autowired
    public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
        this.customerPreferenceDao = customerPreferenceDao;
    }

    // ...
}

如果MovieRecommender只有一个构造方法,那么这个构造方法上的@Autowired注解甚至可以忽略不写(必须是Spring 4.3版本或以上才可以)。

与@Resource一样使用在传统的setter方法上

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Autowired
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // ...
}

比较强悍的是,可以使用在多个属性的方法上,同时注入多个对象,如下所示

public class MovieRecommender {

    private MovieCatalog movieCatalog;

    private CustomerPreferenceDao customerPreferenceDao;

    @Autowired
    public void prepare(MovieCatalog movieCatalog,
            CustomerPreferenceDao customerPreferenceDao) {
        this.movieCatalog = movieCatalog;
        this.customerPreferenceDao = customerPreferenceDao;
    }

    // ...
}

也可以综合以上姿势进行使用,比如

public class MovieRecommender {

    private final CustomerPreferenceDao customerPreferenceDao;

    @Autowired
    private MovieCatalog movieCatalog;

    @Autowired
    public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
        this.customerPreferenceDao = customerPreferenceDao;
    }

    // ...
}

另外还可以将对象注入到集合对象当中,比如

public class MovieRecommender {

    @Autowired
    private MovieCatalog[] movieCatalogs;

    // ...
}
public class MovieRecommender {

    private Set<MovieCatalog> movieCatalogs;

    @Autowired
    public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) {
        this.movieCatalogs = movieCatalogs;
    }

    // ...
}

还有Map中,这个时候注入的bean对象作为value,对应的bean名称作为key

public class MovieRecommender {

    private Map<String, MovieCatalog> movieCatalogs;

    @Autowired
    public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) {
        this.movieCatalogs = movieCatalogs;
    }

    // ...
}

使用这个注解注入的时候,默认情况下,如果不存在指定类型的bean,容器会抛出异常,可以通过设置这个注解的唯一属性值required=false来避免异常。

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Autowired(required = false)
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // ...
}

当然了,如果使用的是Java 8的话,还有更优雅的方式,如下所示:

public class SimpleMovieLister {

    @Autowired
    public void setMovieFinder(Optional<MovieFinder> movieFinder) {
        ...
    }
}

以上的案例来自于官方文档,如果感兴趣可以直接读官方文档获取更多的姿势哦
官方链接:https://docs.spring.io/spring/docs/5.0.17.RELEASE/spring-framework-reference/core.html#beans-autowired-annotation

以上都是一些关于这个注解的使用方法,那么这个注解是如何起作用的,或者说Spring容器是如何读取到这个注解,然后查找到对应的bean,并注入到另一个bean当中的呢?不言而喻,至少有三个步骤:

1. 解析注解
2. 查找bean
3. 设置属性或者方法参数值

那么以下从这三个方面来探讨。在Spring容器中,完成以上步骤的,也就是执行@Autowired逻辑的是类AutowiredAnnotationBeanPostProcessor.查看一下这个类的继承结构图:
在这里插入图片描述
不妨与另一个类CommonAnnotationBeanPostProcessor(实现@Resource注解的关键类)相比较:

在这里插入图片描述
我们会发现这两个类的继承结构惊人的相似。除了 CommonAnnotationBeanPostProcessor直接实现了InstantiationAwareBeanPostProcessor接口,而AutowiredAnnotationBeanPostProcessor通过继承适配器抽象类InstantiationAwareBeanPostProcessorAdapter来间接实现了同一个接口。后一种方式也是Spring更推崇Spring框架使用者使用的姿势。

NOTE: This interface is a special purpose interface, mainly for internal use within the framework. It is recommended to implement the plain BeanPostProcessor interface as far as possible, or to derive from InstantiationAwareBeanPostProcessorAdapter in order to be shielded from extensions to this interface.

首先查看这个适配器类,无非就是给他的每一个实现的接口必须要覆盖的方法一个默认的实现,这样继承者们在需要使用这些接口的时候就不需要一个一个的覆写了(如果是接口中可以有默认实现的话,是不是就不需要这样了呢?所以这个是适配器类设计的时候java还不支持接口默认实现的语法)。另外这个适配器类与真实接口类之间还有另一个接口SmartInstantiationAwareBeanPostProcessor

与本人相关的其他接口相关的另外两个接口参考本人的博客:
什么是MergedBeanDefinition:https://blog.csdn.net/m0_37607945/article/details/107411096
浅析InstantiationAwareBeanPostProcessor:https://blog.csdn.net/m0_37607945/article/details/107404447

首先来看一下这个接口的定义:

public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {

	/**
	 * Predict the type of the bean to be eventually returned from this
	 * processor's {@link #postProcessBeforeInstantiation} callback.
	 * <p>The default implementation returns {@code null}.
	 * @param beanClass the raw class of the bean
	 * @param beanName the name of the bean
	 * @return the type of the bean, or {@code null} if not predictable
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	@Nullable
	default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

	/**
	 * Determine the candidate constructors to use for the given bean.
	 * <p>The default implementation returns {@code null}.
	 * @param beanClass the raw class of the bean (never {@code null})
	 * @param beanName the name of the bean
	 * @return the candidate constructors, or {@code null} if none specified
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	@Nullable
	default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
			throws BeansException {
		return null;
	}
	/**
	 * Obtain a reference for early access to the specified bean,
	 * typically for the purpose of resolving a circular reference.
	 * <p>This callback gives post-processors a chance to expose a wrapper
	 * early - that is, before the target bean instance is fully initialized.
	 * The exposed object should be equivalent to the what
	 * {@link #postProcessBeforeInitialization} / {@link #postProcessAfterInitialization}
	 * would expose otherwise. Note that the object returned by this method will
	 * be used as bean reference unless the post-processor returns a different
	 * wrapper from said post-process callbacks. In other words: Those post-process
	 * callbacks may either eventually expose the same reference or alternatively
	 * return the raw bean instance from those subsequent callbacks (if the wrapper
	 * for the affected bean has been built for a call to this method already,
	 * it will be exposes as final bean reference by default).
	 * <p>The default implementation returns the given {@code bean} as-is.
	 * @param bean the raw bean instance
	 * @param beanName the name of the bean
	 * @return the object to expose as bean reference
	 * (typically with the passed-in bean instance as default)
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
		return bean;
	}
}

这个接口作为InstantiationAwareBeanPostProcessor接口的一个延续,使用一个回调来获取当前正在实例化的Bean的类型,通过predictBeanType来实现。通过determineCandidateConstructors来获取当前实例化Bean的可用构造器。而getEarlyBeanReference用于获取解决循环依赖问题时的提前暴露对象。

比如第一个方法的使用:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#predictBeanType

@Override
@Nullable
protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
	Class<?> targetType = determineTargetType(beanName, mbd, typesToMatch);

	// Apply SmartInstantiationAwareBeanPostProcessors to predict the
	// eventual type after a before-instantiation shortcut.
	if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
				SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
				Class<?> predicted = ibp.predictBeanType(targetType, beanName);
				if (predicted != null && (typesToMatch.length != 1 || FactoryBean.class != typesToMatch[0] ||
						FactoryBean.class.isAssignableFrom(predicted))) {
					return predicted;
				}
			}
		}
	}
	return targetType;
}

这个方法在Spring中使用的极其广泛:

  1. 判断是否类型匹配
    org.springframework.beans.factory.support.AbstractBeanFactory#isTypeMatch(java.lang.String, org.springframework.core.ResolvableType)
    这个方法来自于BeanFactory接口方法,用于判断对于给定名称的bean的类型与指定的类型是否一致。更确切的说,当我们在来获取一个bean的时候,首先是根据bean的名称去查找,然后在返回的时候,需要去检查返回的对象是否与参数中的类型是一致的,此时就会调用这个isTypeMatch接口了。

  2. 解析依赖
    org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency
    这个方法来源AutowireCapableBeanFactory,用于解析bean工厂中特定的依赖。比如在进@Resource注入的时候,最后就会调用这个接口完成依赖的注入操作。
    在这里插入图片描述

  3. 获取当前bean的类型或者当前bean是否是一个FactoryBean
    org.springframework.beans.factory.support.AbstractBeanFactory#getType
    org.springframework.beans.factory.support.AbstractBeanFactory#isFactoryBean(java.lang.String)

也就是说以上这个接口方法predictBeanType可能在一个Bean的整个生命周期都可能被使用到,实例化、初始化甚至获取Bean最后根据是否FactoryBean决定返回对象时。
而对于determineCandidateConstructors方法就比较单纯了,仅仅在实例化的过程中起作用。
在这里插入图片描述

/**
 * Determine candidate constructors to use for the given bean, checking all registered
 * {@link SmartInstantiationAwareBeanPostProcessor SmartInstantiationAwareBeanPostProcessors}.
 * @param beanClass the raw class of the bean
 * @param beanName the name of the bean
 * @return the candidate constructors, or {@code null} if none specified
 * @throws org.springframework.beans.BeansException in case of errors
 * @see org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
 */
@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
		throws BeansException {

	if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
				SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
				Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
				if (ctors != null) {
					return ctors;
				}
			}
		}
	}
	return null;
}

回想一下,Autowired的亮点之一,可以用构造器注入,而且是支持注解多个构造器,如果存在多个,还会进行一定的选择逻辑选择一个构造器来实例化当前的bean对象,因此判断出可用的构造器是很重要的。
最后一个方法getEarlyBeanReference

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
	Object exposedObject = bean;
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
				SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
				exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
			}
		}
	}
	return exposedObject;
}

使用一个单例bean实例化之后与属性填充之前。针对对应的源码进行简化如下:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
		throws BeanCreationException {

	// Instantiate the bean. 实例化一个bean
	// ...
	if (instanceWrapper == null) {
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	// ...

	// Allow post-processors to modify the merged bean definition. 通过后置处理器修改bean的定义
	// postProcessMergedBeanDefinition 比如CommonAnnotationBeanPostProcessor就是修改
	// RootBeanDefinition#externallyManagedConfigMembers、externallyManagedInitMethods、externallyManagedDestroyMethods
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
		    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			mbd.postProcessed = true;
		}
	}

	// Eagerly cache singletons to be able to resolve circular references
	// even when triggered by lifecycle interfaces like BeanFactoryAware.
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		// 此时只是添加了一个工厂对象,真实执行时还是在填充bean的时候,也就是populateBean
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}

	// Initialize the bean instance.
	Object exposedObject = bean;
	// 填充bean
	populateBean(beanName, mbd, instanceWrapper);
	// 初始化bean
	exposedObject = initializeBean(beanName, exposedObject, mbd);
	// Register bean as disposable.
	registerDisposableBeanIfNecessary(beanName, bean, mbd);
	return exposedObject;
}

以上我们介绍完了SmartInstantiationAwareBeanPostProcessor这个接口,下面我们看看InstantiationAwareBeanPostProcessorAdapter,这个适配器有一堆的回调接口,那么这些接口的在整个Bean的生命周期中执行的先后顺序是怎么样的呢?
postProcessBeforeInstantiation(resolveBeforeInstantiation)
determineCandidateConstructors(bean实例化)
postProcessAfterInstantiation(populateBean)
postProcessProperties(populateBean)
getEarlyBeanReference(populateBean)
applyBeanPostProcessorsBeforeInitialization(initializeBean)
调用初始化方法(initializeBean)
applyBeanPostProcessorsAfterInitialization(initializeBean)

其中postProcessPropertyValuespostProcessProperties是一样的。在Spring 5.1版本中被废弃,使用postProcessProperties代替了。

对于predictBeanType方法,因为使用范围比较广,可能处在整个bean创建的过程中,此处没有排列进去,另外对于getEarlyBeanReference的最真实调用是在一个bean依赖另一个bean,从缓存中获取的时候才会触发,因此执行时间应该是在属性填充的时候,也就是解析依赖的时候。

下面看一下AutowiredAnnotationBeanPostProcessor主要实现的几个方法:
在这里插入图片描述由于存在另一个接口MergedBeanDefinitionPostProcessor,完善一下以上的回调顺序表

  1. postProcessBeforeInstantiation(resolveBeforeInstantiation)
  2. determineCandidateConstructors(bean实例化)
  3. postProcessMergedBeanDefinition(doCreateBean 实例化之后 暴露循环依赖的对象工厂前)
  4. postProcessAfterInstantiation(populateBean)
  5. postProcessProperties(populateBean)
  6. getEarlyBeanReference(populateBean)
  7. applyBeanPostProcessorsBeforeInitialization(initializeBean)
  8. 调用初始化方法(initializeBean)
  9. applyBeanPostProcessorsAfterInitialization(initializeBean)

再删除没有实现的方法,那么简化如下:

  1. determineCandidateConstructors(bean实例化)
  2. postProcessMergedBeanDefinition(doCreateBean 实例化之后 暴露循环依赖的对象工厂前)
  3. postProcessProperties(populateBean)

那么分别来介绍以上的的各个方法:

实例化过程判断可用的构造方法
@Override
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
		throws BeanCreationException {

	// Let's check for lookup methods here..
	if (!this.lookupMethodsChecked.contains(beanName)) {
		try {
			ReflectionUtils.doWithMethods(beanClass, method -> {
				Lookup lookup = method.getAnnotation(Lookup.class);
				if (lookup != null) {
					Assert.state(this.beanFactory != null, "No BeanFactory available");
					LookupOverride override = new LookupOverride(method, lookup.value());
					try {
						RootBeanDefinition mbd = (RootBeanDefinition) this.beanFactory.getMergedBeanDefinition(beanName);
						mbd.getMethodOverrides().addOverride(override);
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanCreationException(beanName,
								"Cannot apply @Lookup to beans without corresponding bean definition");
					}
				}
			});
		}
		catch (IllegalStateException ex) {
			throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
		}
		this.lookupMethodsChecked.add(beanName);
	}

	// Quick check on the concurrent map first, with minimal locking.
	Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
	if (candidateConstructors == null) {
		// Fully synchronized resolution now...
		synchronized (this.candidateConstructorsCache) {
			candidateConstructors = this.candidateConstructorsCache.get(beanClass);
			if (candidateConstructors == null) {
				Constructor<?>[] rawCandidates;
				try {
					rawCandidates = beanClass.getDeclaredConstructors();
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName,
							"Resolution of declared constructors on bean Class [" + beanClass.getName() +
							"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
				}
				List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
				Constructor<?> requiredConstructor = null;
				Constructor<?> defaultConstructor = null;
				Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
				int nonSyntheticConstructors = 0;
				for (Constructor<?> candidate : rawCandidates) {
					if (!candidate.isSynthetic()) {
						nonSyntheticConstructors++;
					}
					else if (primaryConstructor != null) {
						continue;
					}
					AnnotationAttributes ann = findAutowiredAnnotation(candidate);
					if (ann == null) {
						Class<?> userClass = ClassUtils.getUserClass(beanClass);
						if (userClass != beanClass) {
							try {
								Constructor<?> superCtor =
										userClass.getDeclaredConstructor(candidate.getParameterTypes());
								ann = findAutowiredAnnotation(superCtor);
							}
							catch (NoSuchMethodException ex) {
								// Simply proceed, no equivalent superclass constructor found...
							}
						}
					}
					if (ann != null) {
						if (requiredConstructor != null) {
							throw new BeanCreationException(beanName,
									"Invalid autowire-marked constructor: " + candidate +
									". Found constructor with 'required' Autowired annotation already: " +
									requiredConstructor);
						}
						boolean required = determineRequiredStatus(ann);
						if (required) {
							if (!candidates.isEmpty()) {
								throw new BeanCreationException(beanName,
										"Invalid autowire-marked constructors: " + candidates +
										". Found constructor with 'required' Autowired annotation: " +
										candidate);
							}
							requiredConstructor = candidate;
						}
						candidates.add(candidate);
					}
					else if (candidate.getParameterCount() == 0) {
						defaultConstructor = candidate;
					}
				}
				if (!candidates.isEmpty()) {
					// Add default constructor to list of optional constructors, as fallback.
					if (requiredConstructor == null) {
						if (defaultConstructor != null) {
							candidates.add(defaultConstructor);
						}
						else if (candidates.size() == 1 && logger.isInfoEnabled()) {
							logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
									"': single autowire-marked constructor flagged as optional - " +
									"this constructor is effectively required since there is no " +
									"default constructor to fall back to: " + candidates.get(0));
						}
					}
					candidateConstructors = candidates.toArray(new Constructor<?>[0]);
				}
				else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
					candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
				}
				else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
						defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
				}
				else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor};
				}
				else {
					candidateConstructors = new Constructor<?>[0];
				}
				this.candidateConstructorsCache.put(beanClass, candidateConstructors);
			}
		}
	}
	return (candidateConstructors.length > 0 ? candidateConstructors : null);
}

这个方法足足120多行,阅读起来有点费劲。针对以上方法进行简化,首先去掉关于注解@Lookup的部分代码,然后再去掉关于缓存的部分代码,首先是获取这个类的所有构造方法

// candidateConstructors = this.candidateConstructorsCache.get(beanClass);
rawCandidates = beanClass.getDeclaredConstructors();

然后定义了三个局部集合变量,分别用于存放与@Required@Primary注解相关的构造器和默认的构造器

Constructor<?> requiredConstructor = null;
Constructor<?> defaultConstructor = null;
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);

遍历所有的构造器,在构造方法上获取在集合autowiredAnnotationTypes中的注解类型,这个集合是在构造的时候传入的值

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.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
	}
	catch (ClassNotFoundException ex) {
		// JSR-330 API not available - simply skip.
	}
}

包括AutowiredValueInject

for (Constructor<?> candidate : rawCandidates) {
	// 获取构造上的
	AnnotationAttributes ann = findAutowiredAnnotation(candidate);
	...
}
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);

@Nullable
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
	if (ao.getAnnotations().length > 0) {  // autowiring annotations have to be local
		for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
			AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
			if (attributes != null) {
				return attributes;
			}
		}
	}
	return null;
}

如果没有在构造方法上获取到相关的注解属性,那么可能当前类是一个被代理的类,比如说被CGLIB代理的类,那么需要首先找到原来的类,通过getUserClass来获取用户定义的类。

org.springframework.util.ClassUtils#getUserClass(java.lang.Class<?>)

/** The CGLIB class separator: {@code "$$"}. */
public static final String CGLIB_CLASS_SEPARATOR = "$$";

/**
 * Return the user-defined class for the given class: usually simply the given
 * class, but the original class in case of a CGLIB-generated subclass.
 * @param clazz the class to check
 * @return the user-defined class
 */
public static Class<?> getUserClass(Class<?> clazz) {
	if (clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) {
		Class<?> superclass = clazz.getSuperclass();
		if (superclass != null && superclass != Object.class) {
			return superclass;
		}
	}
	return clazz;
}

在针对这个类和参数类型获取构造器,然后查找目标注解类属性值,作为AnnotationAttributes对象返回。

Class<?> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
	try {
		Constructor<?> superCtor =
				userClass.getDeclaredConstructor(candidate.getParameterTypes());
		ann = findAutowiredAnnotation(superCtor);
	}
	catch (NoSuchMethodException ex) {
		// Simply proceed, no equivalent superclass constructor found...
	}
}

如果关于Autowired这些注解的属性值不为null,并且注解中required为true的作为requiredConstructor,但只能为一个。如果包含了@Autowired这类注解的构造器,都会加入到candidates集合中,作为后续继续处理的对象。而如果没有包含类似@Autowired这样的注解但是有一个构造器没有任何的参数,作为默认构造。

if (ann != null) {
	if (requiredConstructor != null) {
		throw new BeanCreationException(beanName,
				"Invalid autowire-marked constructor: " + candidate +
				". Found constructor with 'required' Autowired annotation already: " +
				requiredConstructor);
	}
	boolean required = determineRequiredStatus(ann);
	if (required) {
		if (!candidates.isEmpty()) {
			throw new BeanCreationException(beanName,
					"Invalid autowire-marked constructors: " + candidates +
					". Found constructor with 'required' Autowired annotation: " +
					candidate);
		}
		requiredConstructor = candidate;
	}
	candidates.add(candidate);
}
else if (candidate.getParameterCount() == 0) {
	defaultConstructor = candidate;
}
/**
 * Determine if the annotated field or method requires its dependency.
 * <p>A 'required' dependency means that autowiring should fail when no beans
 * are found. Otherwise, the autowiring process will simply bypass the field
 * or method when no beans are found.
 * @param ann the Autowired annotation
 * @return whether the annotation indicates that a dependency is required
 */
protected boolean determineRequiredStatus(AnnotationAttributes ann) {
	return (!ann.containsKey(this.requiredParameterName) ||
			this.requiredParameterValue == ann.getBoolean(this.requiredParameterName));
}

最后针对以上的candidates列表进行统一的处理

if (!candidates.isEmpty()) {
    // 如果存在构造方法,那么包含required=true的构造方法必须在是这个默认构造方法 
	// Add default constructor to list of optional constructors, as fallback.
	if (requiredConstructor == null) {
		if (defaultConstructor != null) {
			candidates.add(defaultConstructor);
		}
		else if (candidates.size() == 1 && logger.isInfoEnabled()) {
			logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
					"': single autowire-marked constructor flagged as optional - " +
					"this constructor is effectively required since there is no " +
					"default constructor to fall back to: " + candidates.get(0));
		}
	}
	candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
// 如果当前类的构造只有一个 而且 参数个数大于0 那么直接返回这个构造
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
	candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
// 如果primaryConstructor和defaultConstructor都存在,那么返回这两个构造 
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
		defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
	candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
// 返回primaryConstructor
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
	candidateConstructors = new Constructor<?>[] {primaryConstructor};
}
// 空
else {
	candidateConstructors = new Constructor<?>[0];
}

比如如下

package com.example.managingtransactions;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MovieRecommender {

    private final CustomerPreferenceDao customerPreferenceDao;

    @Autowired
    private MovieCatalog movieCatalog;

    @Autowired
    public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
        this.customerPreferenceDao = customerPreferenceDao;
    }

    // ...
}

在这里插入图片描述

实例化之后进行注解元数据解析
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
	InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
	metadata.checkConfigMembers(beanDefinition);
}

查找注解@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;
}

以上主要是缓存逻辑,而构造元数据在方法buildAutowiringMetadata

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

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

		ReflectionUtils.doWithLocalFields(targetClass, field -> {
			AnnotationAttributes 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;
			}
			AnnotationAttributes 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 new InjectionMetadata(clazz, elements);
}

在当前类中查找@Autowired元数据,遍历每个属性、每个方法、并且不断遍历其父类,然后构造``InjectionMetadata```对象。

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

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

		ReflectionUtils.doWithLocalFields(targetClass, field -> {
		    // 对属性的处理
			currElements.add(new AutowiredFieldElement(field, required));
		});

		ReflectionUtils.doWithLocalMethods(targetClass, method -> {
			// 对方法的处理
			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);
}

对于每个属性的处理

// 查找Autowired注解属性
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
	// Autowired不能作用于静态属性
	if (Modifier.isStatic(field.getModifiers())) {
		if (logger.isInfoEnabled()) {
			logger.info("Autowired annotation is not supported on static fields: " + field);
		}
		return;
	}
	// 获取required属性值
	boolean required = determineRequiredStatus(ann);
	// 构造AutowiredFieldElement对象
	currElements.add(new AutowiredFieldElement(field, required));
}
public AutowiredFieldElement(Field field, boolean required) {
	super(field, null);
	this.required = required;
}
protected InjectedElement(Member member, @Nullable PropertyDescriptor pd) {
	this.member = member;
	this.isField = (member instanceof Field);
	this.pd = pd;
}

在这里插入图片描述
对于每个方法的处理,同样构建AutowiredMethodElement对象。

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.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));
}

通过以上的方法最后会将关于@Autowired等注解的元数据存放到AutowiredFieldElement,然后再存放到InjectionMetadata,最后再存放到缓存injectionMetadataCache中。
在这里插入图片描述

依赖注入

首先调用findAutowiringMetadata获取当前bean的注解信息,因为此时在缓存中已经存在了,直接从缓存injectionMetadataCache中获取即可。

@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;
}

然后调用InjectionMetadata的注入方法。

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);
		}
	}
}

最终会调用到方法org.springframework.beans.factory.annotation.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;
					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;
			}
		}
	}
	if (value != null) {
		// 通过反射设置属性值
		ReflectionUtils.makeAccessible(field);
		field.set(bean, value);
	}
}

以上的代码先不看缓存相关的最终无非做了两件事,首先根据依赖的描述、当前bean名称、依赖的bean名称、类型转换器获取依赖目标对象。

value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);

在这里插入图片描述

然后通过反射设置到当前bean的属性当中

ReflectionUtils.makeAccessible(field);
field.set(bean, value);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lang20150928

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

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

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

打赏作者

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

抵扣说明:

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

余额充值