与朋友聊到了一个博客上给出的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方法:
- org.springframework.beans.factory.annotation.InjectionMetadata#inject
- org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject 进入 beanFactory.resolveDependency
- org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency
- org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency
- org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveMultipleBeans 进入 findAutowireCandidates
- org.springframework.beans.factory.support.DefaultListableBeanFactory#findAutowireCandidates 进入 BeanFactoryUtils.beanNamesForTypeIncludingAncestors
- org.springframework.beans.factory.BeanFactoryUtils#beanNamesForTypeIncludingAncestors(org.springframework.beans.factory.ListableBeanFactory, java.lang.Class<?>, boolean, boolean)
- org.springframework.beans.factory.support.DefaultListableBeanFactory#getBeanNamesForType(java.lang.Class<?>, boolean, boolean)
- org.springframework.beans.factory.support.DefaultListableBeanFactory#doGetBeanNamesForType 遍历所有bean定义名称,获取bean并校验是否符合传入的指定类型(是否为其子类、实现类)
- org.springframework.beans.factory.support.AbstractBeanFactory#isTypeMatch(java.lang.String, org.springframework.core.ResolvableType)
- org.springframework.core.ResolvableType#isAssignableFrom(java.lang.Class<?>)
方法中获取到了bean的依赖属性并进行了填充,完成了属性自动注入