Spring中具有多个实现类的接口集合是如何自动注入的?(List如何autowired)

与朋友聊到了一个博客上给出的demo,一个接口集合可以自动注入所有实现类,这种spring注入的写法在工作中还不太常见,一般这种我们见框架里使用SPI的形式居多

测试代码

// 定义接口
public interface MultiService {
}

// 实现类1
@Service
public class MultiServiceImpl1 implements MultiService {
}

// 实现类2
@Service
public class MultiServiceImpl2 implements MultiService {
}

// 注入测试
@Service
public class TestService {

    @Autowired
    private List<MultiService> multiServices;

}

经测试,multiServices 会成功被注入两个实现类,这是如何做到的呢?

了解SpringIOC过程的伙伴们都知道,multiServices作为TestService类的成员变量,会在创建TestService这个Bean的时候被作为属性进行填充,将这个“populateBean”作为debug的起点

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

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

		...
		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
            // 进行属性填充
			populateBean(beanName, mbd, instanceWrapper);
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		...

		return exposedObject;
	}

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

		...

		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    // 使用AutowiredAnnotationBeanPostProcessor后置处理器填充autowired的属性
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						if (filteredPds == null) {
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}
		}
		
    ...

	}

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

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

一路跟进metadata.inject方法:

  1. org.springframework.beans.factory.annotation.InjectionMetadata#inject
  2. org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject 进入 beanFactory.resolveDependency
  3. org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency
  4. org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency
  5. org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveMultipleBeans 进入 findAutowireCandidates
  6. org.springframework.beans.factory.support.DefaultListableBeanFactory#findAutowireCandidates 进入 BeanFactoryUtils.beanNamesForTypeIncludingAncestors
  7. org.springframework.beans.factory.BeanFactoryUtils#beanNamesForTypeIncludingAncestors(org.springframework.beans.factory.ListableBeanFactory, java.lang.Class<?>, boolean, boolean)
  8. org.springframework.beans.factory.support.DefaultListableBeanFactory#getBeanNamesForType(java.lang.Class<?>, boolean, boolean)
  9. org.springframework.beans.factory.support.DefaultListableBeanFactory#doGetBeanNamesForType 遍历所有bean定义名称,获取bean并校验是否符合传入的指定类型(是否为其子类、实现类)
  10. org.springframework.beans.factory.support.AbstractBeanFactory#isTypeMatch(java.lang.String, org.springframework.core.ResolvableType)
  11. org.springframework.core.ResolvableType#isAssignableFrom(java.lang.Class<?>)

方法中获取到了bean的依赖属性并进行了填充,完成了属性自动注入

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值