0
点赞
收藏
分享

微信扫一扫

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的依赖属性并进行了填充,完成了属性自动注入

举报

相关推荐

0 条评论