从宏观角度分析Spring源码之DI

2020-05-08  本文已影响0人  皮__皮卡丘

    上篇文章讲解了IOC容器的初始化,将所有需要加载的Bean的定义(BeanDefinition)放入到了beanDefinitionMap中以等待后续的实例化和依赖注入。翻过源码的铁子们一定知道Bean的实例化和依赖注入过程的调用链非常繁杂,为了便于理解,将抛弃Spring框架中对细节的处理,从源码中抽取一条鲜明且具有代表性的主线进行分析。

1、概念

    DI的全称是Dependency Injection,即依赖注入。通俗点来说,在A对象被创建的时候,由容器动态地将A所依赖的其他对象的引用注入进来。例如:Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过容器控制程序来将B对象在外部new出来并注入到A类里的引用中。

2、DI流程描述

  依赖注入主要有两大步骤来实现:

(1)Bean的实例化

(2)Bean属性的依赖注入

3、DI源码分析

    首先要明确一点,依赖注入的过程是第一次调用getBean()方法的时候触发的,但是,如果设置了lazy-init属性为false,依赖注入的过程会由IOC容器直接完成。

    废话少说,直接上时序图:

    通过时序图能清晰地看到依赖注入的整个调用流程, 一般情况下我们会通过ApplicationContext来调用getBean()方法,然而打开源码一看getBean()方法是由ApplicationContext的父接口BeanFactory定义的,这就是依赖注入发生的起点。在整个调用链条中,依赖注入最主要的两个方法是createBeanInstance()和populateBean(),下面着重分析下这两个方法。

    在createBeanInstance()方法中对Bean进行了实例化,即生成了Bean的对象,这个Bean实例的生成有不同的方式,可以通过工厂模式生成,也可以构造函数生成,采用哪种生成方式是由BeanDefinition来决定的。来看下createBeanInstance()的源码:

```

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {

// Make sure bean class is actually resolved at this point.

Class<?> beanClass = resolveBeanClass(mbd, beanName);

if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {

throw new BeanCreationException(mbd.getResourceDescription(), beanName,

"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());

}

Supplier<?> instanceSupplier = mbd.getInstanceSupplier();

if (instanceSupplier != null) {

return obtainFromSupplier(instanceSupplier, beanName);

}

        //使用工厂方法对Bean进行实例化

if (mbd.getFactoryMethodName() != null) {

return instantiateUsingFactoryMethod(beanName, mbd, args);

}

// Shortcut when re-creating the same bean...

boolean resolved = false;

boolean autowireNecessary = false;

if (args == null) {

synchronized (mbd.constructorArgumentLock) {

if (mbd.resolvedConstructorOrFactoryMethod != null) {

resolved = true;

autowireNecessary = mbd.constructorArgumentsResolved;

}

}

}

        //使用构造函数进行实例化

if (resolved) {

if (autowireNecessary) {

return autowireConstructor(beanName, mbd, null, null);

}

else {

return instantiateBean(beanName, mbd);

}

}

// Candidate constructors for autowiring?

Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||

mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {

return autowireConstructor(beanName, mbd, ctors, args);

}

// Preferred constructors for default construction?

ctors = mbd.getPreferredConstructors();

if (ctors != null) {

return autowireConstructor(beanName, mbd, ctors, null);

}

// No special handling: simply use no-arg constructor.

return instantiateBean(beanName, mbd);

}

```

而最常用的实例化方法是通过 instantiateBean()来完成的,如下:

```

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {

try {

Object beanInstance;

final BeanFactory parent = this;

if (System.getSecurityManager() != null) {

beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->

getInstantiationStrategy().instantiate(mbd, beanName, parent),

getAccessControlContext());

}

else {

beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

}

BeanWrapper bw = new BeanWrapperImpl(beanInstance);

initBeanWrapper(bw);

return bw;

}

catch (Throwable ex) {

throw new BeanCreationException(

mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);

}

}

```

    使用默认的策略对Bean进行实例化,查看源码可以发现,默认实例化策略是使用CGLIB动态代理对Bean进行实例化的。

```

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory

implements AutowireCapableBeanFactory {

/** Strategy for creating bean instances. */

private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

```

    通过createBeanInstance()方法的调用完成了Bean的实例化过程,在实例化结束后还需要将Bean对象的依赖关系设置好,才能完成整个依赖注入过程,接下来分析依赖注入方法populateBean(),该方法在AbstractAutowireCapableBeanFactory中,源码如下: 

```

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

if (bw == null) {

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.

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {

for (BeanPostProcessor bp : getBeanPostProcessors()) {

if (bp instanceof InstantiationAwareBeanPostProcessor) {

InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {

return;

}

}

}

}

            //获取beanDefinition中设置的property值

PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

int resolvedAutowireMode = mbd.getResolvedAutowireMode();

            //开始依赖注入

if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {

MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

// Add property values based on autowire by name if applicable.

                //根据name进行注入

if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {

autowireByName(beanName, mbd, bw, newPvs);

}

// Add property values based on autowire by type if applicable.

                //根据type进行注入

if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {

autowireByType(beanName, mbd, bw, newPvs);

}

pvs = newPvs;

}

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();

boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

PropertyDescriptor[] filteredPds = null;

if (hasInstAwareBpps) {

if (pvs == null) {

pvs = mbd.getPropertyValues();

}

for (BeanPostProcessor bp : getBeanPostProcessors()) {

if (bp instanceof InstantiationAwareBeanPostProcessor) {

InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

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;

}

}

}

if (needsDepCheck) {

if (filteredPds == null) {

filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

}

checkDependencies(beanName, mbd, filteredPds, pvs);

}

if (pvs != null) {

                //对属性进行注入

applyPropertyValues(beanName, mbd, bw, pvs);

}

}

```

    通过源码可以看到依赖注入方式有name注入和type注入两种方式,最后调用applyPropertyValues(beanName, mbd, bw, pvs)方法对Bean依赖的属性进行赋值,至此完成依赖注入过程。

    由于是站在宏观的角度来分析Spring的源码,主要是把握主线思路,细节是不做讲解的,如有需要可以留言进行讨论。下篇文章将对Spring的AOP源码实现进行分析!

此文章原地址:https://blog.csdn.net/qq_27324761/article/details/105940919

上一篇下一篇

猜你喜欢

热点阅读