3, 注解spring-Bean依赖处理

上篇博客探讨了spring加载bean的大致流程, 今天我们更加深入的了解Bean加载时的依赖处理。

案例

TestBean05 和TestBean04被spring管理, 其中和TestBean04依赖TestBean05, 我们看看spring是如何注入TestBean05?

TestBean05.java

@Component
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class TestBean05 {

}

TestBean04.java, 依赖于TestBean05

@Component
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class TestBean04 {

    @Autowired
    private TestBean05 testBean05;

    public void print(){
        System.out.println("testBean05 == null:" + (testBean05 == null));
        System.out.println(testBean05.getClass());
    }


}

SpringTest03.java

public static void main(String[] args) {

    String packageName = SpringTest03.class.getPackage().getName();
    AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(packageName);
    TestBean04 testBean04 = (TestBean04)annotationConfigApplicationContext.getBean("testBean04");
    System.out.println(testBean04.getClass());
    testBean04.print();
}

源码解析

--1, SpringTest03.java-->
new AnnotationConfigApplicationContext(packageName);


--2, AnnotationConfigApplicationContext.java-->
public AnnotationConfigApplicationContext(String... basePackages) {
    this();
    scan(basePackages);
    // 这边点进去
    refresh();
}

--3, AbstractApplicationContext-->
@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        prepareRefresh();
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        prepareBeanFactory(beanFactory);
        try {
            ...
            registerListeners();
            // 点进去
            finishBeanFactoryInitialization(beanFactory);
            finishRefresh();
        }
    }
}

上面的代码特别的复杂, 特别的多, 这里有一个小技巧, 打断点
_EF2917BF-5433-4238-9F6F-426FB031EA8F__20200803165005.jpg

此时断点停在registerListeners()的时候, ((DefaultListableBeanFactory) beanFactory).singletonObjects 中并没有发现我们自己的bean

_6A16F976-9FC2-4832-9D88-6E596AD65C49__20200803165654.jpg

而断点到finishRefresh(); 里面就有了那么应该是在finishBeanFactoryInitialization(beanFactory) 这里生成bean的


--4, AbstractApplicationContext-->
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    ...
    beanFactory.freezeConfiguration();
    // (点进去)
    beanFactory.preInstantiateSingletons();
}

--5, AbstractApplicationContext-->
@Override
public void preInstantiateSingletons() throws BeansException {
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (isFactoryBean(beanName)) {
            ...
        }
        else {
            // 点进去
            getBean(beanName);
        }
    }
}

--6, AbstractApplicationContext-->
@Override
public Object getBean(String name) throws BeansException {
    // 点进去
    return doGetBean(name, null, null, false);
}

--7, AbstractApplicationContext -->
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
    ...
    if (mbd.isSingleton()) {
        // 点进去
        sharedInstance = getSingleton(beanName, () -> {
            return createBean(beanName, mbd, args);
        });
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }
    ...
    return (T) bean;
}

--8, DefaultSingletonBeanRegistry.java-->
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        // getObject()就是调用上面的7中的return createBean(...)
        singletonObject = singletonFactory.getObject();
        return singletonObject;
    }
}


--9, AbstractAutowireCapableBeanFactory.java-->
// 直接回到7中的createBean(), 然后点进去
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {
    // 发现了do, (点进去)
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    return beanInstance;

}


--10, AbstractAutowireCapableBeanFactory-->
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {
    instanceWrapper = createBeanInstance(beanName, mbd, args);

    Object exposedObject = bean;
    try {
        populateBean(beanName, mbd, instanceWrapper);
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
}


--11, AbstractAutowireCapableBeanFactory-->
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    ...
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

    PropertyDescriptor[] filteredPds = null;
    if (hasInstAwareBpps) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                        // 点进去
                PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                pvs = pvsToUse;
            }
        }
    }
}

--12, -->
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
    try {
        // 点进去
        metadata.inject(bean, beanName, pvs);
    }
    return pvs;
}


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


--14, AutowiredAnnotationBeanPostProcessor-->
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    Field field = (Field) this.member;
    Object value;
    // 获取依赖信息(testBean05)
    DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
    desc.setContainingClass(bean.getClass());
    Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
    TypeConverter typeConverter = beanFactory.getTypeConverter();
    ...
    try {
        // 处理依赖(点进去)
        value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
    }
    // 反射设置值    
    if (value != null) {
        ReflectionUtils.makeAccessible(field);
        field.set(bean, value);
    }
}

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

        ...前面各种判断
        // 点进去
        result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
        return result;
    }
}

--16, DefaultListableBeanFactory-->
@Nullable
    public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
            @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

    if (instanceCandidate instanceof Class) {
        // 点进去
        instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
    }
    
}

--17, DependencyDescriptor-->
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
            throws BeansException {
    // 这边有回到beanFactory.getBean
    return beanFactory.getBean(beanName);
}



项目地址

总结

spring依赖处理:是一个递归的过程
比如: A依赖B, B依赖C

  1. 先获取一个A的对象(此时依赖没有注入)
  2. 发现A依赖B, 再去获取B对象(beanFactory.getBean(...))
  3. 获取到B对象(依赖没有注入), 发现B依赖C, 再去获取C对象(beanFactory.getBean(...))
  4. 获取C对象, 发现C没有依赖, 返回C, 注入到B中, 再返回B注入到A中