Spring 属性填充(自动装配)源码解析

声明:文章内容仅代表个人对源码的理解和观点,可能存在理解错误的地方,欢迎留言探讨、指正。不喜勿喷,谢谢。
个人用的是 v5.2.4.RELEASE 版本的源码,因为几年前阅读时已经写了一些注释,所以没有拉取最新的源码,与最新的源码会存在一定的差异。

现在我用Spring声明一个Bean,以及Bean之间的依赖关系,基本上都是用注解来完成的。声明一个Bean就用@Component@Service@Repository@Controller等注解;声明Bean之间的依赖关系就在字段上使用 @Autowired@Resource等注解。
JavaConfig有时候也会用,至于XML的配置方式个人现在就用得非常少了。
所以这篇文章主要讲一讲Spring是如何对@Autowired@Resource等注解进行自动注入的。

Spring的自动装配模式

Spring支持按名称、按类型、按构造函数等多种模式进行自动装配。枚举值定义在AutowireCapableBeanFactory接口中,源码如下:

public interface AutowireCapableBeanFactory extends BeanFactory {
	/**
	 * 没有显式定义自动装配模式。
	 * 自动装配模式的默认值。
	 * 有些人说这个模式是不进行自动装配,其实是不对的。
	 * 例如在Bean的字段上使用 @Autowired 注解进行自动注入,在Bean定义中的自动装配模式就是这个,但是Spring会进行自动装配。
	 */
	int AUTOWIRE_NO = 0;

	/**
	 * 按属性名称自动装配。
	 * Spring读取Bean的字段名称,然后将字段名称作为BeanName在IoC容器中查找Bean,找到了就进行注入。
	 * 注意:字段必须有对应的set方法。
	 */
	int AUTOWIRE_BY_NAME = 1;

	/**
	 * 按类型自动装配
	 * Spring获取Bean字段的类型,然后通过类型从IoC容器中查找Bean,找到了就进行注入。
	 * 注意:字段也必须有对应的set方法
	 */
	int AUTOWIRE_BY_TYPE = 2;

	/**
	 * 按构造函数自动装配,发生在实例化阶段
	 */
	int AUTOWIRE_CONSTRUCTOR = 3;

	/**
	 * 由Spring自己选择使用哪种自动装配模式
	 * 如果无法使用无参构造函数实例化,例如Bean没有无参构造函数,只有一个有参构造函数,则使用构造函数自动装配。
	 * 如果能使用无参构造函数实例化,则在属性填充时按类型自动装配。
	 * 具体的判断逻辑可以查看 AbstractBeanDefinition.getResolvedAutowireMode() 方法
	 * 该模式从 Spring 3.0 开始废弃。
	 */
	@Deprecated
	int AUTOWIRE_AUTODETECT = 4;
    // 后面省略大量代码。。。。。。
}

需要说明的几个点:

  1. 通过注解声明的Bean,Spring扫描组件生成的Bean定义对象中,自动装配模式默认是AUTOWIRE_NO
  2. 使用JavaConfig配置的Bean,自动装配模式默认是AUTOWIRE_CONSTRUCTOR,可以使用@Bean注解的autowire属性配置自动装配模式,不过这个属性在Spring 5.1版本中被声明废弃了。
  3. 使用XML配置Bean,则通过bean标签autowire属性指定自动装配模式。

如何查看一个Bean的自动装配模式?
查看Bean定义对象中的 private int autowireMode = AUTOWIRE_NO; 属性,该属性在抽象类 AbstractBeanDefinition 中,默认值为0。但是Spring在判断到底使用哪种自动装配模式的时候,除了这个属性,还有一些其他因素需要考虑,例如在使用构造函数实例化Bean时,判断是否属于构造函数自动装配的代码如下:

/*
 * chosenCtors 是添加了 @Autowired 注解的构造函数,此时在Bean定义中的 autowireMode 属性值为0,
 * 但是最终的判断结果可能是使用构造函数自动注入。
 */
boolean autowiring = (chosenCtors != null ||
					mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);

自动装配相关的注解

@Autowired

  • @Autowired 注解可以用在构造函数、方法(一般用在setter方法)、参数(方法参数、构造函数参数)、字段、以及其它注解。
  • 主要作用是声明自动装配/注入,默认按照类型进行注入,并且被注入的对象默认不能为null,否则抛出异常,可以将 required 属性设置为false,允许被注入的值为null。
  • 如果想要按照Bean的名称进行注入,需要结合 @Qualifier 注解使用。
  • 用在构造函数,则表示使用此构造函数进行实例化,即构造函数自动注入。
  • 用在方法,则表示使用此方法进行注入,此方法可以不是setter方法。
  • 用在参数,只能表示此参数是否为必填,并不能表示使用此方法或者构造函数进行自动装配。
  • 用在字段,则表示此字段需要进行自动注入。
  • 用在其他注解上,则是一个复合注解,一个注解具有多个注解的功能。最经典的复合注解莫过于@SpringBootApplication

@Inject

  • javax.inject.Inject 注解可以用在 构造函数、方法、字段。
  • 此注解没有 required 属性,它的效果相当于 @Autowired(required=true)

@Resource

  • javax.annotation.Resource 注解可以用在方法、字段、类。
  • 此注解也能声明自动注入,默认按名称进行注入,如果找不到与名称匹配的Bean,则按照类型进行注入。

@Qualifier

  • @Qualifier 注解可以用在方法、参数(方法参数、构造函数参数)、字段、其它注解、类。但是不能用在构造函数上。
  • Spring支持 javax.inject.Qualifier,但是此注解只能用在其它注解上面,如果需要使用此注解,则实际需要使用 javax.inject.Named
  • 主要作用是在自动注入时,选择指定的BeanName的实例。

@Primary

  • @Primary 注解,标记这个Bean是主要的。可以用在类和方法上。
  • 一个class可以定义多个Bean,如果没有通过BeanName显式说明注入哪个Bean,则会注入这个"主要的Bean";如果既没有指定BeanName,又没有配置Primary Bean,会抛出异常。

@Priority

  • javax.annotation.Priority 注解,设置Bean的优先级,值越小,优先级越高。
  • 其作用与 @Primary 相似,如果两个或以上的Bean优先级相同,则会抛出异常。
  • 该注解只能用在类和参数上,所以它主要用于一个接口,多个实现类的场景。

@Value

  • @Value 注解可以用在方法、参数、字段、其它注解。
  • 主要作用是读取Spring环境变量中的参数值进行注入。

属性填充源码解析

说明:
构造函数的自动装配流程这篇博文不做分析。
循环依赖注入的流程也不做分析,要分析循环依赖,可以单独写一篇了。

Bean的生命周期 可以分为 实例化、属性填充、初始化、销毁。
所以属性填充发生在实例化之后,初始化之前,主流程在AbstractAutowireCapableBeanFactory.populateBean()方法,此方法在AbstractAutowireCapableBeanFactory.doCreateBean()方法中被调用。源码如下:

// AbstractAutowireCapableBeanFactory
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
		throws BeanCreationException {
	// Instantiate the bean.
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	/*
	 * 第一步:实例化Bean。
	 * 构造函数注入发生在这一步
	 */
	if (instanceWrapper == null) {
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = instanceWrapper.getWrappedInstance();
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}
	// Allow post-processors to modify the merged bean definition.
	/*
	 * 合并Bean定义
	 * CommonAnnotationBeanPostProcessor
	 * 查找类中使用了 @PostConstruct 和 @PreDestroy 注解的方法,并注册到Bean定义中,这类方法在Bean初始化和销毁时被执行
	 * 检查类中使用了 @Resource @EJB @WebServiceRef 注解的字段和方法,并注册到Bean定义中
	 * AutowiredAnnotationBeanPostProcessor
	 * 查找类上使用了 @Autowired、@Value、@Inject 注解的字段和方法,将这些字段和方法添加到Bean定义中
	 */
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			}
			catch (Throwable ex) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Post-processing of merged bean definition failed", ex);
			}
			mbd.postProcessed = true;
		}
	}
       // 省略部分代码,这一部分代码是提前暴露Bean的引用,用于解决循环依赖。。。。。。
	Object exposedObject = bean;
	try {
		// 第二步:填充属性/依赖注入
		populateBean(beanName, mbd, instanceWrapper);

		// 第三步:初始化Bean。
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
	catch (Throwable ex) {
		// 异常处理,省略......
	}
	// 循环依赖处理,省略。。。。。。
	return exposedObject;
}

合并自动装配注解到Bean定义

在进行属性填充之前,使用MergedBeanDefinitionPostProcessor处理器获取 Bean Class 中添加了自动装配注解的字段、方法,并将这些字段、方法注册到Bean定义中。
用到的 MergedBeanDefinitionPostProcessor 处理器主要有两个:

  • AutowiredAnnotationBeanPostProcessor 处理 @Autowired@Value@Inject 注解的字段和方法。
  • CommonAnnotationBeanPostProcessor 处理 @Resource@EJB@WebServiceRef 注解的字段和方法。

调用 MergedBeanDefinitionPostProcessor 处理器的源码如下:

// AbstractAutowireCapableBeanFactory
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
	for (BeanPostProcessor bp : getBeanPostProcessors()) {
		if (bp instanceof MergedBeanDefinitionPostProcessor) {
			MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
			/*
			 * CommonAnnotationBeanPostProcessor
			 * 查找类中使用了 @PostConstruct 和 @PreDestroy 注解的方法,并注册到Bean定义
			 * 查找类中使用了 @Resource @EJB @WebServiceRef 注解的字段和方法,并注册到Bean定义
			 * AutowiredAnnotationBeanPostProcessor
			 * 查找类中使用了 @Autowired、@Value、@Inject 注解的字段和方法,并注册到Bean定义
			 * PersistenceAnnotationBeanPostProcessor
			 * 查找类中使用了 @PersistenceContext、PersistenceUnit 注解的字段和方法,并注册到Bean定义
			 */
			bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
		}
	}
}

AutowiredAnnotationBeanPostProcessor的源码如下:

// AutowiredAnnotationBeanPostProcessor
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
	// 查找类中使用了 @Autowired、@Value、@Inject 注解的字段和方法,并将这些字段和方法封装到"注入元数据"对象中,后面的自动装配就是通过这个对象来完成的
	InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
	metadata.checkConfigMembers(beanDefinition); // 注册到Bean定义
}

// 该方法在属性填充的时候还会被调用,只是那时候直接从缓存中获取数据,无须再次解析
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.
	// 先从缓存中找,在属性填充之前读取这些字段、方法合并到Bean定义中,后面进行属性填充时,就直接从这个缓存中获取了。
	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);
				}
				// 查找类中使用了 @Autowired、@Value、@Inject 注解的字段和方法,并将这些字段和方法封装到"注入元数据"对象中
				metadata = buildAutowiringMetadata(clazz);
				this.injectionMetadataCache.put(cacheKey, metadata);
			}
		}
	}
	return metadata;
}

// 获取使用了 @Autowired、@Value、@Inject 注解的方法、字段的主要代码
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<>();
		// 遍历类中的所有字段,查找是否有 @Autowired、@Value、@Inject 注解的字段,并添加到列表
		ReflectionUtils.doWithLocalFields(targetClass, field -> {
			// 先获取字段上的所有注解,然后再匹配查找字段上的@Autowired、@Value、@Inject注解,有则返回,没有则为null
			MergedAnnotation<?> ann = findAutowiredAnnotation(field);
			if (ann != null) { // 如果字段上有自动注入的注解
				if (Modifier.isStatic(field.getModifiers())) { // 字段不能是 static 的
					// 打印日志,省略 。。。。。。
					return;
				}
				// 获取注解的 required 属性值,如果没有这个属性,默认为true。表示是否必填
				boolean required = determineRequiredStatus(ann);
				currElements.add(new AutowiredFieldElement(field, required));
			}
		});
		
		// 遍历类中的所有方法,查找是否有 @Autowired、@Value、@Inject 注解的方法,并添加到列表
		ReflectionUtils.doWithLocalMethods(targetClass, method -> {
			/*
			 * 此处的桥接方法,并非设计模式中的桥接模式
			 * 当父类/接口方法的参数是泛型,而子类/实现类的方法参数是具体的类型时,编译器在编译的时候会生成一个桥接方法,类似于编译器自动给我们重载了一个方法
			 * 或者当子类重写父类的方法时,如果子类的参数类型与父类的参数类型不一样,编译器也会自动生成一个桥接方法
			 */
			Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
			if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
				return;
			}
			// 查找方法上的 @Autowired、@Value、@Inject注解,有则返回,没有则为null
			MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
			// 获取class上的真实方法,因为method可能是一个桥接方法
			if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
				if (Modifier.isStatic(method.getModifiers())) { // 不能是static的
					// 打印日志,省略 。。。。。。
					return;
				}
				if (method.getParameterCount() == 0) {
					// 打印日志,省略 。。。。。。
				}
				// 获取注解的 required 属性值,如果没有这个属性,默认为true。表示是否必填
				boolean required = determineRequiredStatus(ann);
				// 先获取类上的所有属性,然后判断方法是否为某个属性的 getter 或 setter 方法,如是则返回对应的属性,否则返回null
				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);

	// 生成一个 InjectionMetadata对象
	return InjectionMetadata.forElements(elements, clazz);
}

将使用了自动装配注解的方法、字段注册到Bean定义:

// InjectionMetadata
// 将含有 @Resource @EJB @WebServiceRef @Autowired @Value @Inject 注解的字段和方法添加到Bean定义中
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
	Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
	for (InjectedElement element : this.injectedElements) {
		Member member = element.getMember();
		// Bean定义中是否已经存在该字段或者方法
		if (!beanDefinition.isExternallyManagedConfigMember(member)) {
		    // 注册到Bean定义中
			beanDefinition.registerExternallyManagedConfigMember(member);
			checkedElements.add(element);
			// 打印日志,省略 。。。。。。
		}
	}
	this.checkedElements = checkedElements;
}

代码逻辑整理:

  1. 找到 Bean Class 被 @Autowired @Value @Inject 注解的字段,并且不能被 static 关键字修饰,如果存在这样的字段,则读取注解的 required 属性值,用于判定此字段的属性值是否允许为null。
  2. 找到 Bean Class 被 @Autowired @Value @Inject 注解的方法,并且也不能被 static 关键字修饰,如果存在这样的方法,则读取注解的 required 属性值,用于判断此方法注入的值是否允许为null。
  3. 将找到的字段、方法添加到缓存injectionMetadataCache,在后面进行自动装配的时候还需要获取这些字段、方法,到时直接从缓存中就能获取,无须再次解析。进行自动装配时,取的是这个缓存中的值。
  4. 将找到的字段、方法注册到Bean定义对象中。

CommonAnnotationBeanPostProcessor 处理 @Resource @EJB @WebServiceRef 注解的逻辑与 AutowiredAnnotationBeanPostProcessor 的逻辑极为相似,这里就不再列出来了,因为这篇文档已经太长了。
关于 @Resource 注解的解析,在 CommonAnnotationBeanPostProcessor#ResourceElement 类的构造函数中完成,获取对应的 name 属性、type 属性、lookup 属性等等。代码很简单,想看的同学可以自己看一看。

属性填充的主流程 populateBean

// AbstractAutowireCapableBeanFactory
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
	// Bean为null,则说明对象没有实例化
	if (bw == null) {
	    // Bean实例为null,但是Bean定义中有显式配置的参数,则抛出异常
		if (mbd.hasPropertyValues()) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
		}
		else {
			// Skip property population phase for null instance.
			return;
		}
	}

	// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
	// state of the bean before properties are set. This can be used, for example,
	// to support styles of field injection.
	/*
	 * 到这里bean已经实例化完成了,但是还没给属性设值。
	 * InstantiationAwareBeanPostProcessor 的实现类可以在这里对 bean 进行状态修改。
	 * 官方的解释是:让用户可以自定义属性注入。这是 Spring 留给我们自己扩展的接口。
	 * 默认情况下,这一部分代码什么都没做
	 */
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { // 是否持有 InstantiationAwareBeanPostProcessor
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				/*
				 * 在Bean实例化之后,属性填充之前调用
				 * 如果该方法返回false,代表不需要进行后续的属性设值;返回true,则进行正常的属性设置。
				 * CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor、InstantiationAwareBeanPostProcessorAdapter 什么都没有做,直接返回true
				 * ConfigurationClassPostProcessor#ImportAwareBeanPostProcessor 继承 InstantiationAwareBeanPostProcessorAdapter,没有重写该方法,所以也直接返回true
				 */
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}
	}

	// 在xml中通过 property 子标签显式定义的属性值
	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
	// 显式配置的自动注入模式,默认值0。
	int resolvedAutowireMode = mbd.getResolvedAutowireMode();
	/*
	 * 按名称或者类型进行自动注入。
	 * 使用注解、JavaConfig配置的Bean,自动注入模式默认都是0。
	 * xml中定义的Bean,则由bean标签的autowire属性决定。
	 * 所以,默认情况下是不走这里的。
	 */
	if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
		// Add property values based on autowire by name if applicable.
		// 按名称自动注入,注入的字段必须要有set方法
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}
		// Add property values based on autowire by type if applicable.
		// 按类型自动注入,注入的字段必须要有set方法
		if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			autowireByType(beanName, mbd, bw, newPvs);
		}
		pvs = newPvs;
	}
       // 是否有 InstantiationAwareBeanPostProcessor 处理器,一般为true
	boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
	boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); // 是否需要检查依赖

	PropertyDescriptor[] filteredPds = null;
	if (hasInstAwareBpps) {
		if (pvs == null) {
			pvs = mbd.getPropertyValues();
		}
		// 调用 InstantiationAwareBeanPostProcessor 处理器进行属性填充
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				/*
				 * ConfigurationClassPostProcessor#ImportAwareBeanPostProcessor 判断 Bean 是否实现了 EnhancedConfiguration 接口,如果是则回调方法,设置Bean工厂到Bean中,然后直接返回参数 pvs
				 * PersistenceAnnotationBeanPostProcessor 处理 @PersistenceContext 和 @PersistenceUnit 注解的注入
				 * ScriptFactoryPostProcessor 则是直接返回参数 pvs
				 * CommonAnnotationBeanPostProcessor 处理 @Resource @EJB @WebServiceRef 注解的属性填充
				 * AutowiredAnnotationBeanPostProcessor 处理 @Autowired、@Value、@Inject 注解的属性填充
				 * CommonAnnotationBeanPostProcessor和AutowiredAnnotationBeanPostProcessor最终都会调用到 InjectionMetadata.inject() 的同一个方法,由此可见,这些注解的注入方式是一样的
				 * 显式定义的属性不在这里处理
				 */
				PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				/*
				 * pvsToUse 即参数值 pvs,不会为null,所以下面的这个分支不会被执行。
				 * 之所以有这段代码,这应该是Spring对旧版本的支持。
				 * 因为上面的 postProcessProperties 方法是从 5.1 版本开始提供的,下面的 postProcessPropertyValues 方法在 5.1 版本被废弃了
				 */
				if (pvsToUse == null) {
					if (filteredPds == null) {
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
					}
					// postProcessPropertyValues 方法以及被废弃,Spring应该是推荐使用上面的 postProcessProperties 方法处理自动注入。其实最终也是调用的 postProcessProperties 方法
					pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						return;
					}
				}
				pvs = pvsToUse;
			}
		}
	}
	// 检查依赖
	if (needsDepCheck) {
		if (filteredPds == null) {
			filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		}
		checkDependencies(beanName, mbd, filteredPds, pvs);
	}

	// 显式配置的参数的装配流程
	if (pvs != null) {
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
}

populateBean方法主要做了如下几件事情:

  1. 调用InstantiationAwareBeanPostProcessor处理器,此处理器能够让开发者自定义Bean的属性填充流程,并且根据返回值决定是否需要继续执行后面的属性填充逻辑。默认情况下什么都没有做,所以可以忽略这一步对属性填充的影响。
  2. 检查是否显式配置了自动装配模式,按照显示配置的自动装配模式从IoC容器中获取对应属性的参数值。注意:这里只是获取注入属性的值,并没有进行自动注入。
  3. 调用 InstantiationAwareBeanPostProcessor 处理器,对@Autowired@Value@Inject@Resource@EJB@WebServiceRef 注解的字段和方法进行属性填充。主要的处理器也是 CommonAnnotationBeanPostProcessorAutowiredAnnotationBeanPostProcessor
  4. 对在Bean定义中显式配置的参数、按名称自动装配、按类型自动装配的字段进行依赖注入。

@Autowired@Value@Inject 注解的自动装配流程

@Autowired@Value@Inject 注解的字段、方法是通过 AutowiredAnnotationBeanPostProcessor 处理器来完成自动装配的,源码如下:

// AutowiredAnnotationBeanPostProcessor
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
	// 获取有 @Autowired、@Value、@Inject 注解的字段和方法,在执行属性填充之前已经进行了解析,这里直接从缓存中获取
	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;
}

首先找到 Bean Class 中被 @Autowired@Value@Inject 注解的字段和方法,然后进行自动装配。关于findAutowiringMetadata方法的源码,可以返回去查看自动装配注解合并到Bean定义章节中的源码。
接下来看一下自动注入的源码:

// InjectionMetadata
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    // 需要进行注入的方法或字段。@Autowired、@Value、@Inject @Resource @EJB @WebServiceRef
	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);
			}
			/*
			 * 自动注入
			 * 方法注入是 AutowiredMethodElement
			 * 字段注入是 AutowiredFieldElement
			 */
			element.inject(target, beanName, pvs);
		}
	}
}
字段自动注入 AutowiredFieldElement

字段自动注入 AutowiredAnnotationBeanPostProcessor#AutowiredFieldElement 的源码如下:

// 参数说明:A 需要注入 B,bean是A,beanName是A的BeanName,pvs是显式配置的属性值
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
	Field field = (Field) this.member; // 待进行注入的字段
	Object value; // 属性值
	if (this.cached) {
 		/*
		 * 已经缓存了参数值,则直接取缓存。
		 * 如果缓存值的类型是 ShortcutDependencyDescriptor,则可以直接取值
		 * 如果缓存值的类型是 DependencyDescriptor ,还是需要重新解析的
		 * 重新解析也是调用 beanFactory.resolveDependency 方法
		 */
		value = resolvedCachedArgument(beanName, this.cachedFieldValue);
	}
	else {
	    // 属性的一些信息,例如属性的名称、类型等
		DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
		desc.setContainingClass(bean.getClass());
		// 自动注入的BeanName集合,用于维护Bean之间的依赖关系
		Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
		Assert.state(beanFactory != null, "No BeanFactory available");
		TypeConverter typeConverter = beanFactory.getTypeConverter(); // 默认是 SimpleTypeConverter
		try {
			/*
			 * 这是注入的核心
			 * 从IoC容器中获取属性值,可能是一个Bean,也可能是一个配置参数。如果是Bean有可能是二级缓存中的Bean
			 * 该方法是解析依赖值的核心逻辑
			 */
			value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
		}
		catch (BeansException ex) {
			throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
		}
		// 注册Bean之间的依赖关系、缓存参数值
		synchronized (this) {
			if (!this.cached) {
				if (value != null || this.required) {
					this.cachedFieldValue = desc;
					registerDependentBeans(beanName, autowiredBeanNames); // 注册Bean之间的依赖关系
					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);
	}
}

对字段进行自动注入的逻辑相对比较简单,先获取参数值,然后通过反射进行设值就行。复杂的逻辑在获取参数值 beanFactory.resolveDependency() 方法中,这个方法的源码在后文已贴出。

setter方法自动注入 AutowiredMethodElement

setter方法自动注入AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement的源码如下:

// 参数说明:A 需要注入 B,bean是A,beanName是A的BeanName,pvs是显式配置的属性值
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
	// 如果setter方法或者对应的字段已经显式配置了参数,则无须做解析,直接跳过
	if (checkPropertySkipping(pvs)) {
		return;
	}
	Method method = (Method) this.member; // 进行属性注入的方法
	Object[] arguments; // 方法的参数值容器
	if (this.cached) { // 方法参数已经缓存了,说明以前有被解析过,所以直接拿来用,与字段注入一样
		// Shortcut for avoiding synchronization...
		arguments = resolveCachedArguments(beanName);
	}
	else {
		int argumentCount = method.getParameterCount(); // 方法参数的个数
		arguments = new Object[argumentCount];
		DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
		Set<String> autowiredBeans = new LinkedHashSet<>(argumentCount); // 自动注入的BeanName,用于维护Bean之间的依赖关系
		Assert.state(beanFactory != null, "No BeanFactory available");
		TypeConverter typeConverter = beanFactory.getTypeConverter();
		for (int i = 0; i < arguments.length; i++) { // 遍历方法的参数,一个一个的找
			MethodParameter methodParam = new MethodParameter(method, i);
			DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
			currDesc.setContainingClass(bean.getClass());
			descriptors[i] = currDesc;
			try {
				/*
				 * 这是注入的核心
				 * 从IoC容器中获取用于注入的值。如果是Bean有可能是二级缓存中的Bean,其实主要的逻辑就在这个方法中
				 * 这是自动注入获取参数值的核心
				 */
				Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
				if (arg == null && !this.required) {
					arguments = null;
					break;
				}
				arguments[i] = arg;
			}
			catch (BeansException ex) {
				throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
			}
		}
		// 注册Bean之间的依赖关闭,缓存参数孩子
		synchronized (this) {
			if (!this.cached) {
				if (arguments != null) {
					DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
					registerDependentBeans(beanName, autowiredBeans); // 注册Bean之间的依赖关系
					if (autowiredBeans.size() == argumentCount) {
						Iterator<String> it = autowiredBeans.iterator(); // 用于注入的BeanName迭代器
						Class<?>[] paramTypes = method.getParameterTypes(); // 方法的参数类型列表
						for (int i = 0; i < paramTypes.length; i++) {
							String autowiredBeanName = it.next();
							if (beanFactory.containsBean(autowiredBeanName) &&
									beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) { // IoC容器中存在用于注入的Bean,并参数类型匹配,则进行缓存
								// 缓存中的类型是 ShortcutDependencyDescriptor,则不再需要解析,如果是 DependencyDescriptor 类型,则需要再次解析
								cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
										descriptors[i], autowiredBeanName, paramTypes[i]);
							}
						}
					}
					this.cachedMethodArguments = cachedMethodArguments; // 缓存方法参数,用于依赖注入的值
				}
				else {
					this.cachedMethodArguments = null;
				}
				this.cached = true; // 缓存标记设置为已缓存
			}
		}
	}
	// 通过反射的方式调用方法,进行属性注入
	if (arguments != null) {
		try {
			ReflectionUtils.makeAccessible(method);
			method.invoke(bean, arguments);
		}
		catch (InvocationTargetException ex) {
			throw ex.getTargetException();
		}
	}
}

通过setter方法进行自动注入的流程和通过字段进行自动注入的流程是相似的,都是先获取待注入的属性值,然后通过反射设值,也是通过 beanFactory.resolveDependency() 方法获取参数值。

解析依赖 DefaultListableBeanFactory.resolveDependency() 方法

resolveDependency方法中的代码比较简单,直接上源码:

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

	descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); // 初始化获取参数名称的策略
	// 前面几个分支都是对一些特殊类型的处理,主要关注最后一个分支,那才是我们经常用到的方式
	if (Optional.class == descriptor.getDependencyType()) { // 参数类型是不是Optional
		return createOptionalDependency(descriptor, requestingBeanName);
	}
	else if (ObjectFactory.class == descriptor.getDependencyType() ||
			ObjectProvider.class == descriptor.getDependencyType()) { // 参数类型是不是 ObjectFactory 或者 ObjectProvider
		return new DependencyObjectProvider(descriptor, requestingBeanName);
	}
	else if (javaxInjectProviderClass == descriptor.getDependencyType()) { // 参数类型是不是 javax.inject.Provider
		return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
	}
	else {
		/*
		 * 一般都是走这个分支
		 * getAutowireCandidateResolver() 获取自动装配解析器
		 * 如果是xml中的Bean定义指定为构造函数注入(autowire="constructor"),则是SimpleAutowireCandidateResolver
		 * 如果是注解,则是ContextAnnotationAutowireCandidateResolver
		 * SimpleAutowireCandidateResolver.getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName)直接返回null
		 * ContextAnnotationAutowireCandidateResolver.getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName)如果是延迟加载,则返回一个代理对象,否则也是返回null
		 */
		Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
				descriptor, requestingBeanName);
		if (result == null) {
			 // 真正进行依赖解析的方法,找到用于依赖注入的对象,如果该对象是IoC容器中的Bean,并且还没有创建,则在这里会被创建
			result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
		}
		return result;
	}
}

真正解析依赖的逻辑在doResolveDependency方法中,再上源码:

// DefaultListableBeanFactory
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
		@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
	// 设置当前正在进行注入的对象,例如A需要注入B,这里是将B设置到ThreadLocal。ThreadLocal获取上一个注入的对象,并将当前注入的对象设置到ThreadLocal。
	InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
	try {
		// 快捷解析(ShortcutDependencyDescriptor),经过解析之后,缓存的对象一般就是快捷创建了
		Object shortcut = descriptor.resolveShortcut(this);
		// 快捷解析结果存在,则直接返回了
		if (shortcut != null) {
			return shortcut;
		}

		Class<?> type = descriptor.getDependencyType(); // 参数/属性的类型
		/*
		 * @Value注解的处理流程。依赖的是Bean的话,返回值为null。
		 * getAutowireCandidateResolver()方法默认返回 SimpleAutowireCandidateResolver。当开启注解时返回 ContextAnnotationAutowireCandidateResolver
		 * SimpleAutowireCandidateResolver.getSuggestedValue()方法直接返回null
		 * 主要看一下 ContextAnnotationAutowireCandidateResolver 的代码,getSuggestedValue()方法在其父类 QualifierAnnotationAutowireCandidateResolver,用于获取@Value注解的value属性,参数值还没有被解析,是一个Spring表达式
		 */
		Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
		if (value != null) {
			if (value instanceof String) { // @Value注解的解析流程
				String strVal = resolveEmbeddedValue((String) value); // 解析Spring表达式(${}),拿到配置参数值
				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()));
			}
		}

		/*
		 * 判断参数是不是数组、Collection、Map等可以放多个Bean的类型
		 * 如果是,则找到所有类型的Bean,并返回一个多值对象;如果不是,则返回null
		 */
		Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
		if (multipleBeans != null) {
			return multipleBeans;
		}
		/*
		 * 参数不是数组、List、Map之类的,则会走这里
		 * 查找用可以依赖注入的Bean:参数类型匹配,BeanName与 @Qualifier 指定的BeanName匹配。Bean如果没有创建完成(不存在一级缓存中),value是该Bean的class
		 */
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
		// 如果找不到符合条件的Bean,并且这个参数又是必填(required=true,默认值是true),则抛出异常。如果不是必填则返回null
		if (matchingBeans.isEmpty()) {
			if (isRequired(descriptor)) {
				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
			}
			return null;
		}

		String autowiredBeanName; // 主动注入的BeanName
		Object instanceCandidate; // 自动注入对象,例如A需要注入B,这个对象是B

		if (matchingBeans.size() > 1) { // 存在多个可以用于自动注入的对象
			// 查找@Primary Bean,或者优先级@Priority最高的Bean的BeanName,或者从自定义的“类型 -> 实例”映射关系中找
			autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
			// 找不到符合条件的Bean,又是必填,则抛出异常
			if (autowiredBeanName == null) {
				if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
					// 找不到符合条件的Bean,抛出NoUniqueBeanDefinitionException异常,说明IoC里面有多个可以用于注入的Bean,Spring不知道用哪一个
					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); // 添加到自动注入的Bean名称集合中,用于在外层注册Bean之间的依赖关系
		}
		if (instanceCandidate instanceof Class) { // 如果Bean还没有创建完成(没有进入一级缓存),则创建Bean(beanFactory.getBean(beanName))
			instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
		}
		Object result = instanceCandidate; // 这里获取到的可能是一级缓存中的Bean,也可能是二级缓存中的Bean
		// 没有找到依赖注入的对象,并且Bean定义时指定了 required 属性为true(默认值true),则抛出异常
		if (result instanceof NullBean) {
			if (isRequired(descriptor)) { // Bean不存在,并且是必须注入,则抛出异常
				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); // 重置ThreadLocal中的值,set旧值
	}
}

简单整理一下 doResolveDependency方法的逻辑:

  1. 判断是不是 @Value 注解,如果是则先获取Spring表达式,然后获取配置参数值。参数值通过最终使用的 PropertySourcesPropertyResolver.resolvePlaceholders()方法(父类 AbstractPropertyResolver) 解析Spring表达式,拿到配置参数值。关于Spring表达式的解析有兴趣的可以自己看一看,这里就不贴源码了。
  2. 判断参数类型是不是数组、Collection、Map等。如果是,则找到参数类型在IoC容器中的所有Bean,并创建一个多值对象返回;如果不是,则返回值为null。这一段逻辑是比较简单的,可以自己看一看,这里也不贴源码了。
  3. 从IoC容器中找出参数类型的所有Bean,这里会匹配@Qualifier指定的BeanName。
  4. 如果找到了多个Bean,则判断@Primary@Priority注解,找到 Primary Bean 或优先级最高的Bean,如果找到多个,会抛出异常。
  5. 上面找到的Bean可能是没有完全创建完成的实例。只有已经存在一级缓存中的Bean返回的是实例,其它返回的是Bean Class。对于后者,则需要完成Bean的创建,调用beanFactory.getBean(beanName)方法。
  6. 异常处理。例如没有找到需要的Bean实例,而属性值有不允许为null,或者Bean的类型与参数类型不匹配等,都会抛出异常。
匹配 @Qualifier 的BeanName

这里的代码比较长,但是逻辑不复杂,将这一部分源码贴出来,供有想看的同学看一看,不做过多的说明,看注释基本就知道Spring是怎么完成BeanName匹配的。

// DefaultListableBeanFactory
protected Map<String, Object> findAutowireCandidates(
		@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
	/*
	 * 在IoC容器中查找 requiredType(需要注入的对象类型,例如A需要注入B,requiredType是B的类型) 类型的所有Bean的BeanName
	 * 一个类可以被定义成多个Bean,这里会全部找到
	 */
	String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
			this, requiredType, true, descriptor.isEager());
	Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
	/*
	 * 判断依赖的Bean类型(requiredType)是否是BeanFactory\ResourceLoader\ApplicationContext\ApplicationEventPublisher等类型或子类
	 */
	for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
		Class<?> autowiringType = classObjectEntry.getKey();
		// 判定requiredType与autowiringType是否相同,或者是autowiringType的子类,成立返回true
		if (autowiringType.isAssignableFrom(requiredType)) {
			// 自动装配的值,例如A需要注入B,这个对象代表的是对象B
			Object autowiringValue = classObjectEntry.getValue();
			// 根据给定的类型(requiredType)解析给定的自动装配值(autowiringValue),例如ObjectFactory值(提前暴露的引用)到它的实际对象。
			autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
			if (requiredType.isInstance(autowiringValue)) { // autowiringValue对象 是 requiredType类型的实例
				result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
				break;
			}
		}
	}
	// 遍历 requiredType 类型注册在IoC容器中的所有BeanName
	for (String candidate : candidateNames) {
		/*
		 * isSelfReference方法判断是不是自己依赖自己,beanName是正在创建的Bean的名称,candidate是requiredType的Bean名称。
		 * 如果不是自身循环依赖,则检查candidate(这是一个beanName)对应的Bean是否是我们需要注入的Bean:
		 * 首先检查此Bean是否可以用于依赖注入(bean 的 autowire-candidate 属性不能被设置为“false”),然后判断此Bean的类型是否匹配;
		 * 上面成立之后,再检查此Bean的BeanName与@Qualifier指定的BeanName是否匹配,如果没有@Qualifier注解,则返回true。
		 */
		if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
			// 当前变量(candidate)的Bean是注入需要的Bean,则添加到返回值 result 对象中,Bean如果已经创建完成,存的是Bean实例,否则(Bean还没有进入一级缓存)存的是Bean的类型 class
			addCandidateEntry(result, candidate, descriptor, requiredType);
		}
	}
	if (result.isEmpty()) { // 如果上面的方法没有找到用于注入的值
		boolean multiple = indicatesMultipleBeans(requiredType); // 判断参数类型是不是数组、Collection、Map等
		// Consider fallback matches if the first pass failed to find anything... 如果第一遍找不到任何东西,请考虑后备匹配...
		DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch(); // 回退匹配,可以看做是泛型的处理
		for (String candidate : candidateNames) { // 重新遍历BeanName
			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;
}
// DefaultListableBeanFactory
public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
		throws NoSuchBeanDefinitionException {
	// 检查 beanName 对应的Bean是否可以用于依赖注入。
	// getAutowireCandidateResolver() 默认返回 SimpleAutowireCandidateResolver,当开启注解时返回 ContextAnnotationAutowireCandidateResolver
	return isAutowireCandidate(beanName, descriptor, getAutowireCandidateResolver());
}

protected boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver)
		throws NoSuchBeanDefinitionException {
	// Bean的真实名称,主要是去除FactoryBean的BeanName前缀符号&
	String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
	// Bean定义映射对象(beanDefinitionMap)中,是否存在当前Bean名称。其实这两个分支执行的是同一个方法
	if (containsBeanDefinition(beanDefinitionName)) {
		/*
		 * 检查beanName对应的Bean是否是我们需要注入的Bean。
		 * 首先检查此Bean是否可以用于依赖注入(bean 的 autowire-candidate 属性不能被设置为“false”),然后判断此Bean的类型是否匹配。
		 * 上面成立之后,再检查此Bean的BeanName与@Qualifier指定的BeanName是否匹配,如果没有@Qualifier注解,则返回true。
		 */
		return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanDefinitionName), descriptor, resolver);
	}
	// Bean定义映射对象中没有,检查IoC容器的一级缓存(singletonObjects)中有没有这个BeanName
	else if (containsSingleton(beanName)) {
		return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver);
	}

	BeanFactory parent = getParentBeanFactory(); // 当前容器中没有这个Bean,则从父容器中匹配
	if (parent instanceof DefaultListableBeanFactory) {
		// No bean definition found in this factory -> delegate to parent.
		return ((DefaultListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor, resolver);
	}
	else if (parent instanceof ConfigurableListableBeanFactory) {
		// If no DefaultListableBeanFactory, can't pass the resolver along.
		return ((ConfigurableListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor);
	}
	else {
		return true;
	}
}

protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
		DependencyDescriptor descriptor, AutowireCandidateResolver resolver) {
	// Bean的真实名称,主要是去除FactoryBean的BeanName前缀符号&
	String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName); // Bean的真实名称
	resolveBeanClass(mbd, beanDefinitionName); // 解析Bean的Class,也可以理解为校验BeanClass是否存在,不存在会抛出异常
	if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) {
		new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
	}
	/*
	 * 检查beanName对应的Bean是否是我们需要注入的Bean。
	 * resolver是ContextAnnotationAutowireCandidateResolver类型,实际调用的是其父类 QualifierAnnotationAutowireCandidateResolver
	 * 首先检查此Bean是否可以用于依赖注入(bean 的 autowire-candidate 属性不能被设置为“false”),然后判断此Bean的类型是否匹配。
	 * 上面成立之后,再检查此Bean的BeanName与@Qualifier指定的BeanName是否匹配,如果没有@Qualifier注解,则返回true。
	 */
	return resolver.isAutowireCandidate(
			new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor);
}
// QualifierAnnotationAutowireCandidateResolver
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
	/*
	 * 调用其父类 GenericTypeAwareAutowireCandidateResolver 的方法,检查被注入Bean的定义,判断此Bean是否可以用于依赖注入,默认为true。然后再判断类型是否匹配,主要写一些泛型的处理。
	 * 例如Bean定义的时候,是否允许用于依赖注入,默认是允许的,然后再检查类型是否匹配
	 * 两者都成立才返回true
	 */
	boolean match = super.isAutowireCandidate(bdHolder, descriptor);
	if (match) { // 可用于依赖注入,再检查@Qualifier注解
		/*
		 * 检查是否有@Qualifier注解,
		 * 如果有则检查Bean定义(bdHolder)中的BeanName与@Qualifier注解中的BeanName是否匹配,匹配值为true。
		 * descriptor.getAnnotations()可以获取字段 或者 方法/构造函数/参数上的注解
		 */
		match = checkQualifiers(bdHolder, descriptor.getAnnotations());
		if (match) {
			MethodParameter methodParam = descriptor.getMethodParameter(); // 获取构造器或方法的参数操作对象,如果是通过字段进行自动注入,这里为null
			if (methodParam != null) {
				Method method = methodParam.getMethod(); // 获取依赖注入的setter方法
				// method = null表示构造函数注入,void.class == method.getReturnType()表示setter方法注入
				if (method == null || void.class == method.getReturnType()) {
					// 检查构造函数或方法是否有@Qualifier注解,并且是否匹配,如果没有@Qualifier注解返回true
					match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
				}
			}
		}
	}
	return match;
}

protected boolean checkQualifiers(BeanDefinitionHolder bdHolder, Annotation[] annotationsToSearch) {
	// 字段/方法/构造函数/参数上的注解为空,则表示没有 @Qualifier 注解,直接返回true,因为无需匹配BeanName
	if (ObjectUtils.isEmpty(annotationsToSearch)) {
		return true;
	}
	SimpleTypeConverter typeConverter = new SimpleTypeConverter();
	for (Annotation annotation : annotationsToSearch) {
		Class<? extends Annotation> type = annotation.annotationType(); // 注解的类型
		boolean checkMeta = true; // 是否检查注解类型上面的注解(元注解)信息,因为当前注解可能是个复合注解
		boolean fallbackToMeta = false;
		// 判断是不是org.springframework.beans.factory.annotation.Qualifier或者javax.inject.Qualifier(javax.inject.Named)注解
		if (isQualifier(type)) {
			// 检查当前Bean定义(bdHolder)中的BeanName与@Qualifier注解中的BeanName是否相同。相同,返回值为true,但是这个表达式的值为false。
			if (!checkQualifier(bdHolder, annotation, typeConverter)) {
				// bdHolder中的BeanName与@Qualifier注解中的BeanName不相同,则需要再次检查注解上面的 @Qualifier 注解
				fallbackToMeta = true;
			}
			else {
				// 如果bdHolder中的BeanName与是@Qualifier注解中的BeanName相同,说明是我们需要的Bean,则不需要再检查元注解了
				checkMeta = false;
			}
		}
		if (checkMeta) { // 检查注解类型上面的注解,当字段/方法/参数上没有 @Qualifier 注解,或者BeanName与 @Qualifier 指定的值不匹配时,则执行这一块代码
			boolean foundMeta = false; // 元注解是否有 Qualifier 注解
			for (Annotation metaAnn : type.getAnnotations()) { // 获取注解类上面的注解
				Class<? extends Annotation> metaType = metaAnn.annotationType();
				// 判断元注解是不是org.springframework.beans.factory.annotation.Qualifier或者javax.inject.Qualifier注解
				if (isQualifier(metaType)) {
					foundMeta = true;
					// Only accept fallback match if @Qualifier annotation has a value...
					// Otherwise it is just a marker for a custom qualifier annotation.
					/*
					 * 如果Bean定义(bdHolder)中的BeanName与字段/方法/参数上的@Qualifier注解执行的值不匹配,并且作为元注解的 Qualifier 没有属性值,
					 * 或者Bean定义(bdHolder)中的BeanName与元注解指定的值还是不匹配,则返回false,说明这个Bean不是我们需要注入的Bean
					 */
					if ((fallbackToMeta && StringUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
							!checkQualifier(bdHolder, metaAnn, typeConverter)) { // 检查BeanName是否相同
						return false;
					}
				}
			}

			// bdHolder中的BeanName与@Qualifier注解中的BeanName不相同,并且相关注解又没有组合 @Qualifier 注解,则说明此Bean不是我们需要注入的Bean,返回false
			if (fallbackToMeta && !foundMeta) {
				return false;
			}
		}
	}
	return true; // 返回true,说明 bdHolder 参数持有的Bean是我们需要的Bean
}

protected boolean checkQualifier(
		BeanDefinitionHolder bdHolder, Annotation annotation, TypeConverter typeConverter) {

	Class<? extends Annotation> type = annotation.annotationType(); // 注解的类型
	RootBeanDefinition bd = (RootBeanDefinition) bdHolder.getBeanDefinition(); // Bean定义信息

	AutowireCandidateQualifier qualifier = bd.getQualifier(type.getName()); // 从Bean定义中获取指定的注解信息
	if (qualifier == null) {
		qualifier = bd.getQualifier(ClassUtils.getShortName(type)); // 使用类型短名称,再次尝试从Bean定义中获取注解信息
	}
	if (qualifier == null) {
		// First, check annotation on qualified element, if any
		// 从Bean定义中的 qualifiedElement 字段上获取相关注解,通过这个字段,在注册Bean定义时,可以自定义注解元素。一般这个字段都是null。
		Annotation targetAnnotation = getQualifiedElementAnnotation(bd, type);
		// Then, check annotation on factory method, if applicable
		if (targetAnnotation == null) {
			targetAnnotation = getFactoryMethodAnnotation(bd, type); // 从工厂方法上面找指定的注解
		}
		if (targetAnnotation == null) { // 这里还是从工厂方法上面查找指定的注解
			RootBeanDefinition dbd = getResolvedDecoratedDefinition(bd);
			if (dbd != null) {
				targetAnnotation = getFactoryMethodAnnotation(dbd, type);
			}
		}
		if (targetAnnotation == null) { // 从Bean的类型class上找指定的注解
			// Look for matching annotation on the target class
			if (getBeanFactory() != null) {
				try {
					Class<?> beanType = getBeanFactory().getType(bdHolder.getBeanName()); // 获取Bean的类型
					if (beanType != null) {
						// 从类上面找对应的注解信息
						targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(beanType), type);
					}
				}
				catch (NoSuchBeanDefinitionException ex) {
					// Not the usual case - simply forget about the type check...
				}
			}
			if (targetAnnotation == null && bd.hasBeanClass()) {
				targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(bd.getBeanClass()), type);
			}
		}
		if (targetAnnotation != null && targetAnnotation.equals(annotation)) {
			return true;
		}
	}

	// 获取注解的属性值,key是注解属性的名称,value是属性的值,例如@Qualifier解析后,key是"value",value是Bean名称
	Map<String, Object> attributes = AnnotationUtils.getAnnotationAttributes(annotation);
	if (attributes.isEmpty() && qualifier == null) {
		// If no attributes, the qualifier must be present
		return false;
	}
	for (Map.Entry<String, Object> entry : attributes.entrySet()) {
		String attributeName = entry.getKey(); // 注解的属性名称
		Object expectedValue = entry.getValue(); // 注解属性的值,期望值
		Object actualValue = null; // 获取实际值,因为注解的属性上可能使用@AliasFor注解指向了其它属性
		// Check qualifier first
		if (qualifier != null) {
			actualValue = qualifier.getAttribute(attributeName);
		}
		if (actualValue == null) {
			// Fall back on bean definition attribute
			actualValue = bd.getAttribute(attributeName);
		}
		// bdHolder.matchesName((String) expectedValue) bdHolder是用于注入的Bean的定义,expectedValue是@Qualifier注解中配置的BeanName,这个方法就是校验dbHolder持有的Bean是不是我们需要的Bean
		if (actualValue == null && attributeName.equals(AutowireCandidateQualifier.VALUE_KEY) &&
				expectedValue instanceof String && bdHolder.matchesName((String) expectedValue)) {
			// Fall back on bean name (or alias) match
			continue;
		}
		if (actualValue == null && qualifier != null) {
			// Fall back on default, but only if the qualifier is present
			actualValue = AnnotationUtils.getDefaultValue(annotation, attributeName); // 获取注解字段的默认值
		}
		if (actualValue != null) {
			actualValue = typeConverter.convertIfNecessary(actualValue, expectedValue.getClass());
		}
		if (!expectedValue.equals(actualValue)) { // 期望值与实际值是否相同
			return false;
		}
	}
	return true;
}
匹配 @Primary@Priority 注解的Bean

这两个注解的匹配逻辑比较简单,代码量也比较少,这里仅贴出源码供想看的同学参考。

// DefaultListableBeanFactory
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
	Class<?> requiredType = descriptor.getDependencyType();
	// 判断Bean定义中的 primary 属性是否为true(@Primary),为true则返回对应的BeanName,如果有多个Primary Bean,会抛出异常
	String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
	if (primaryCandidate != null) {
		return primaryCandidate;
	}

	// 查找优先级最高的Bean,例如在class上使用@Priority设置优先级
	String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
	if (priorityCandidate != null) {
		return priorityCandidate;
	}
	// Fallback
	// 没有设置 @Primary 和 @Priority,则尝试从IoC中配置的"class -> 注入值"关系中查找
	for (Map.Entry<String, Object> entry : candidates.entrySet()) {
		String candidateName = entry.getKey();
		Object beanInstance = entry.getValue();
		if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
				matchesBeanName(candidateName, descriptor.getDependencyName())) {
			return candidateName;
		}
	}
	return null;
}

匹配 @Primary注解的源码:

// DefaultListableBeanFactory
protected String determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType) {
	String primaryBeanName = null;
	for (Map.Entry<String, Object> entry : candidates.entrySet()) {
		String candidateBeanName = entry.getKey();
		Object beanInstance = entry.getValue();
		// 判断Bean定义中的 primary 属性是否为true,当存在 @Primary 注解时,该属性值为true
		if (isPrimary(candidateBeanName, beanInstance)) {
			if (primaryBeanName != null) { // 如果存在多个PrimaryBean则抛出异常
				boolean candidateLocal = containsBeanDefinition(candidateBeanName);
				boolean primaryLocal = containsBeanDefinition(primaryBeanName);
				if (candidateLocal && primaryLocal) {
					throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
							"more than one 'primary' bean found among candidates: " + candidates.keySet());
				}
				else if (candidateLocal) {
					primaryBeanName = candidateBeanName;
				}
			}
			else {
				primaryBeanName = candidateBeanName;
			}
		}
	}
	return primaryBeanName;
}

protected boolean isPrimary(String beanName, Object beanInstance) {
	String transformedBeanName = transformedBeanName(beanName);
	// 如果Bean定义存在当前容器中
	if (containsBeanDefinition(transformedBeanName)) {
	    // 获取Bean定义的 primary 属性,当Bean定义时使用了 @Primary 注解,该属性值为true
		return getMergedLocalBeanDefinition(transformedBeanName).isPrimary();
	}
    // 如果自身容器没有,则检查父容器中的Bean定义
	BeanFactory parent = getParentBeanFactory();
	return (parent instanceof DefaultListableBeanFactory &&
			((DefaultListableBeanFactory) parent).isPrimary(transformedBeanName, beanInstance));
}

匹配 @Priority 注解的源码:

// DefaultListableBeanFactory
protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) {
	String highestPriorityBeanName = null; // 当前最高优先级的Bean名称
	Integer highestPriority = null; // 当前最高的优先级别
	for (Map.Entry<String, Object> entry : candidates.entrySet()) {
		String candidateBeanName = entry.getKey();
		Object beanInstance = entry.getValue();
		if (beanInstance != null) {
			// 获取Bean的优先级,例如从class上获取 javax.annotation.Priority 注解的 value 属性值
			Integer candidatePriority = getPriority(beanInstance);
			if (candidatePriority != null) {
				if (highestPriorityBeanName != null) {
					if (candidatePriority.equals(highestPriority)) { // 如果有两个优先级相同的Bean,抛出异常
						throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
								"Multiple beans found with the same priority ('" + highestPriority +
								"') among candidates: " + candidates.keySet());
					}
					else if (candidatePriority < highestPriority) { // 维护最高优先级的Bean,值越小,优先级越高
						highestPriorityBeanName = candidateBeanName;
						highestPriority = candidatePriority;
					}
				}
				else {
					highestPriorityBeanName = candidateBeanName;
					highestPriority = candidatePriority;
				}
			}
		}
	}
	return highestPriorityBeanName;
}

protected Integer getPriority(Object beanInstance) {
	Comparator<Object> comparator = getDependencyComparator(); // AnnotationAwareOrderComparator
	if (comparator instanceof OrderComparator) {
		return ((OrderComparator) comparator).getPriority(beanInstance); // 获取 javax.annotation.Priority 注解的 value 属性值
	}
	return null;
}

// AnnotationAwareOrderComparator
public Integer getPriority(Object obj) {
	if (obj instanceof Class) {
		return OrderUtils.getPriority((Class<?>) obj); // 获取 javax.annotation.Priority 注解的 value 属性值
	}
	Integer priority = OrderUtils.getPriority(obj.getClass());
	if (priority == null  && obj instanceof DecoratingProxy) {
		return getPriority(((DecoratingProxy) obj).getDecoratedClass());
	}
	return priority;
}

@Resource 注解的自动装配流程

@Resource注解的字段、方法是通过 CommonAnnotationBeanPostProcessor 处理器来完成自动装配的,源码如下:

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
	// 从缓存中获取有 @Resource @EJB @WebServiceRef 注解的字段和方法上,在执行属性填充之前,已经进行过解析了
	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;
}

最终调用的也是 InjectionMetadata.inject() 方法,与@Autowired 等注解的处理流程是一样的。

按名称自动填充 autowireByName

获取 Bean Class 中符合条件的属性名称,将属性名称当做 BeanName 查找Bean,存在则添加到参数列表,这里没有进行自动装配

// AbstractAutowireCapableBeanFactory
protected void autowireByName(
		String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
	// 获取非静态、有set方法、不在显式定义参数中、不是简单类型(String、枚举、基本类型及其包装类型等)的 Bean class 中的字段名称
	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
	for (String propertyName : propertyNames) { // 遍历字段名称
	    // IoC的一级缓存或者Bean定义映射(beanDefinitionMap)中,是否存在以字段名称为BeanName的Bean
		if (containsBean(propertyName)) {
		    // 存在,则获取Bean对象,此时可能会创建Bean
			Object bean = getBean(propertyName);
			pvs.add(propertyName, bean); // 添加到显示参数列表
			registerDependentBean(propertyName, beanName); // 注册Bean的依赖关系
			// 日志,省略。。。。。。
		}
		else {
			// 日志,省略 。。。。。。
		}
	}
}

按类型自动装配 autowireByType

逻辑与按名称自动装配差不多,也是先获取 Bean Class 中符合条件的属性名称进行遍历,找到属性的类型,然后从IoC容器中查找值,并加入参数列表,这里也没有进行自动装配

// AbstractAutowireCapableBeanFactory
protected void autowireByType(
		String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
	TypeConverter converter = getCustomTypeConverter(); // 自定义的类型转换器,默认为null
	if (converter == null) {
		converter = bw; // 没有自定义的,就使用 BeanWrapperImpl
	}

	Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
	// 获取非静态、有set方法、不在显式定义参数中、不是简单类型(String、枚举、基本类型及其包装类型等)的 Bean class 中的字段名称
	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
	for (String propertyName : propertyNames) { // 遍历字段名称
		try {
			// 获取字段操作相关的一个对象,例如字段的名称、类型、对应的set方法等
			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.
			if (Object.class != pd.getPropertyType()) {
			    // 获取字段的set方法
				MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
				// Do not allow eager init for type matching in case of a prioritized post-processor.
				boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
				DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
				// 使用字段的类型从IoC容器中查找Bean
				Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
				if (autowiredArgument != null) {
					pvs.add(propertyName, autowiredArgument); // 找到了就添加到显式参数列表
				}
				for (String autowiredBeanName : autowiredBeanNames) {
					registerDependentBean(autowiredBeanName, beanName); // 注册Bean之间的依赖关系
					// 省略日志 。。。。。。
				}
				autowiredBeanNames.clear();
			}
		}
		catch (BeansException ex) {
			throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
		}
	}
}

这里也使用了 resolveDependency 方法,可以返回去看一下解析依赖 DefaultListableBeanFactory.resolveDependency()方法 部分中的源码。

显式配置参数的注入

关于显式配置的参数的注入就不贴源码了,逻辑不是很复杂,因为都已经知道了哪个属性要设置哪个值。但是,属性值现在可能还只是一个引用,或者是Spring表达式,需要进行转换。获取到真实的属性值之后,还需要判断值与属性的类型是否匹配。逻辑还是比较多的,有兴趣的同学可以自己看一看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值