2. Spring源码解析之IOC(下篇)

2. Spring源码解析之IOC(下篇)

  • 2.3 IOC 容器的依赖注入
    • 2.3.1 依赖注入发生时间
    • 2.3.2 getBean 依赖注入
      • 2.3.2.1 参数为name
      • 2.3.2.2 参数为requiredType
  • 2.4 IOC 容器的高级特性
    • 2.4.1 lazy-init 属性实现预实例化
      • 2.4.1.1 refresh 函数载入 Bean 定义
      • 2.4.1.2 finishBeanFactoryInitialization 处理预实例化
      • 2.4.1.3 DefaultListableBeanFactory 对配置 lazy-init 属性单态 Bean 的预实例化
    • 2.4.2 FactoryBean 实现
    • 2.4.3 BeanPostProcessor 后置处理器
    • 2.4.4 自动装配功能

2.3 IOC 容器的依赖注入

2.3.1 依赖注入发生时间

当 Spring IOC 容器完成了 Bean 定义资源的*定位、载入和解析注册以后,IOC 容器中已经管理类 Bean定义的相关数据,但是此时 IOC 容器还没有对所管理的 Bean 进行依赖注入*,依赖注入在以下两种情况发生:

  • 用户第一次通过 getBean 方法向 IOC 容索要 Bean 时,IOC 容器触发依赖注入。
  • 当用户在 Bean 定义资源中为元素配置了 lazy-init 属性,即让容器在解析注册 Bean 定义时进行预实例化,触发依赖注入。

BeanFactory 接口定义了 Spring IOC 容器的基本功能规范,是 Spring IOC 容器所应遵守的最底层和最基本的编程规范。BeanFactory 接口中定义了几个 getBean 方法,就是用户向 IOC 容器索取管理的 Bean的方法,我们通过分析其子类的具体实现,理解 Spring IOC 容器在用户索取 Bean 时如何完成依赖注入。

2.3.2 getBean 依赖注入

getBean 向 IOC 容器获取被管理的 Bean,有两类方法,一种参数依据name为主,一种参数依据requiredType为主,下面分别说明:

2.3.2.1 参数为name

1)AbstractBeanFactory 通过 getBean 向 IOC 容器获取被管理的 Bean

//获取 IOC 容器中指定名称的 Bean
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}

//获取 IOC 容器中指定名称和类型的 Bean
public <T> T getBean(String name, Class<T> requiredType)
    								throws BeansException {
    return doGetBean(name, requiredType, null, false);
}

//获取 IOC 容器中指定名称和参数的 Bean
public Object getBean(String name, Object... args) 
    								throws BeansException {
    return doGetBean(name, null, args, false);
}

//获取 IOC 容器中指定名称、类型和参数的 Bean
public <T> T getBean(String name, 
                     @Nullable Class<T> requiredType,
                     @Nullable Object... args) throws BeansException {
    return doGetBean(name, requiredType, args, false);
}
protected <T> T doGetBean(final String name,
                          @Nullable final Class<T> requiredType,
                          @Nullable final Object[] args,
                          boolean typeCheckOnly) throws BeansException {

    //根据指定的名称获取被管理 Bean 的名称,剥离指定名称中对容器的相关依赖
	//如果指定的是别名,将别名转换为规范的 Bean 名称
    final String beanName = transformedBeanName(name);
    Object bean;

    //先从缓存中取是否已经有被创建过的单态类型的 Bean
	//对于单例模式的 Bean 整个 IOC 容器中只创建一次,不需要重复创建
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        //获取给定 Bean 的实例对象,主要是完成 FactoryBean 的相关处理
		//注意:BeanFactory 是管理容器中 Bean 的工厂,
        //而 FactoryBean 是创建创建对象的工厂 Bean,两者之间有区别
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
    else {
        //缓存没有正在创建的单例模式 Bean
        //缓存中已经有已经创建的原型模式 Bean
        //但是由于循环引用的问题导致实例化对象失败
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
        //对 IOC 容器中是否存在指定名称的 BeanDefinition 进行检查,
        //首先检查是否能在当前的 BeanFactory 中获取的所需要的 Bean,
        //如果不能则委托当前容器的父级容器去查找,
        //如果还是找不到则沿着容器的继承体系向父级容器查找
        BeanFactory parentBeanFactory = getParentBeanFactory();
        //当前容器的父级容器存在,且当前容器中不存在指定名称的 Bean
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            //解析指定 Bean 名称的原始名称
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory)
                    .doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
            }
            else if (args != null) {
                //委派父级容器根据指定名称和显式的参数查找
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else if (requiredType != null) {
                //委派父级容器根据指定名称和类型查找
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
            else {
                return (T) parentBeanFactory.getBean(nameToLookup);
            }
        }
		//创建的 Bean 是否需要进行类型验证,一般不需要
        if (!typeCheckOnly) {
            //向容器标记指定的 Bean 已经被创建
            markBeanAsCreated(beanName);
        }
        try {
            //根据指定 Bean 名称获取其父级的 Bean 定义
            //主要解决 Bean 继承时子类合并父类公共属性问题
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            //获取当前 Bean 所有依赖 Bean 的名称
            String[] dependsOn = mbd.getDependsOn();
            //如果当前 Bean 有依赖 Bean
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    //判断是否有循环依赖
                    if (isDependent(beanName, dep)) {
                        ...
                    }
                    //把被依赖 Bean 注册给当前依赖的 Bean
                    registerDependentBean(dep, beanName);
                    try {
                        //递归调用 getBean 方法,获取当前 Bean 的依赖 Bean
                        getBean(dep);
                    }
                }
            }

            //创建单例模式 Bean 的实例对象
            if (mbd.isSingleton()) {
                //创建 Bean 实例对象,并且注册给所依赖的对象
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        //创建一个指定 Bean 实例对象,
                        //如果有父级继承,则合并子类和父类的定义
                        return createBean(beanName, mbd, args);
                    }
                });
                //获取给定 Bean 的实例对象
                bean = getObjectForBeanInstance(sharedInstance,
                                                name, beanName, mbd);
            }
			//IOC 容器创建原型模式 Bean 实例对象
            else if (mbd.isPrototype()) {
                //原型模式(Prototype)是每次都会创建一个新的对象
                Object prototypeInstance = null;
                try {
                    //回调 beforePrototypeCreation 方法,
                    //默认的功能是注册当前创建的原型对象
                    beforePrototypeCreation(beanName);
                    //创建指定 Bean 对象实例
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    //回调 afterPrototypeCreation 方法,
                    //默认的功能告诉 IoC 容器指定 Bean 的原型对象不再创建了
                    afterPrototypeCreation(beanName);
                }
                //获取给定 Bean 的实例对象
                bean = getObjectForBeanInstance(prototypeInstance,
                                                name, beanName, mbd);
            }
            //要创建的 Bean 既不是单例模式,也不是原型模式,
            //则根据 Bean 定义资源中配置的生命周期范围,选择实例化 Bean 的合适方法,
            //这种在 Web 应用程序中比较常用,如:request、session、application 等生命周期
            else {
                String scopeName = mbd.getScope();
                final Scope scope = this.scopes.get(scopeName);
                //Bean 定义资源中没有配置生命周期范围,则 Bean 定义不合法
                if (scope == null) {
                    throw new IllegalStateException(
                        "No Scope registered for scope name '" + scopeName + "'");
                }
                try {
                    //获取一个指定生命周期范围的实例
                    Object scopedInstance = scope.get(beanName, () -> {
                        beforePrototypeCreation(beanName);
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        finally {
                            afterPrototypeCreation(beanName);
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance,
                                                    name, beanName, mbd);
                }
            }
        }
        catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }

    //对创建的 Bean 实例对象进行类型检查
    if (requiredType != null && !requiredType.isInstance(bean)) {
        try {
            T convertedBean = getTypeConverter()
                				.convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
                throw new BeanNotOfRequiredTypeException(name,
                                                         requiredType,
                                                         bean.getClass());
            }
            return convertedBean;
        }
    }
    return (T) bean;
}

通过上面对向 IOC 容器获取 Bean 方法的分析,得到结论:

  • 如果 Bean 定义的单例模式(Singleton),则容器在创建之前先从缓存中查找,以确保整个容器中只存在一个实例对象。
  • 如果 Bean 定义的是原型模式(Prototype),则容器每次都会创建一个新的实例对象。
  • 除此之外,Bean 定义还可以扩展为指定其生命周期范围。

具体的 Bean 实例对象的创建过程由实现了 ObejctFactory 接口的匿名内部类的 createBean 方法完成,具体的 Bean 实例创建过程交由其实现类 AbstractAutowireCapableBeanFactory 完成。

2)AbstractAutowireCapableBeanFactory 创建 Bean 实例对象

//创建 Bean 实例对象
protected Object createBean(String beanName, 
                            RootBeanDefinition mbd,
                            @Nullable Object[] args) throws BeanCreationException {

    
    RootBeanDefinition mbdToUse = mbd;

    //判断需要创建的 Bean 是否可以实例化,即是否可以通过当前的类加载器加载
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null
            && !mbd.hasBeanClass() 
            && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    //校验和准备 Bean 中的方法覆盖
    try {
        mbdToUse.prepareMethodOverrides();
    }

    try {
        //如果 Bean 配置了初始化前和初始化后的处理器,则试图返回一个需要创建 Bean 的代理对象
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }

    try {
        //创建 Bean 的入口
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        return beanInstance;
    }
}
protected Object doCreateBean(final String beanName,
                              final RootBeanDefinition mbd,
                              final @Nullable Object[] args)
									throws BeanCreationException {

    //封装被创建的 Bean 对象
    BeanWrapper instanceWrapper = null;
    //单例模式的 Bean,先从容器中缓存中获取同名 Bean
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        //创建实例对象
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    //调用 PostProcessor 后置处理器
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            }
            
            mbd.postProcessed = true;
        }
    }

    //向容器中缓存单例模式的 Bean 对象,以防循环引用
    boolean earlySingletonExposure = 
        (mbd.isSingleton() && this.allowCircularReferences &&
                                      isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        //为了防止循环引用,尽早持有对象的引用
        addSingletonFactory(beanName, 
                            () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    //Bean 对象的初始化,依赖注入在此触发
	//这个 exposedObject 在初始化完成之后返回作为依赖注入完成后的 Bean
    Object exposedObject = bean;
    try {
        //将 Bean 实例对象封装,并且 Bean 定义中配置的属性值赋值给实例对象
        populateBean(beanName, mbd, instanceWrapper);
        //初始化 Bean 对象
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    //获取指定名称的已注册的单例模式 Bean 对象
    if (earlySingletonExposure) {
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            //根据名称获取的已注册的 Bean 和正在实例化的 Bean 是同一个
            if (exposedObject == bean) {
                //当前实例化的 Bean 初始化完成
                exposedObject = earlySingletonReference;
            }
            //当前 Bean 依赖其他 Bean,并且当发生循环引用时不允许新创建实例对象
            else if (!this.allowRawInjectionDespiteWrapping 
                     && hasDependentBean(beanName)) {
                //获取当前 Bean 所依赖的其他 Bean
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = 
                    new LinkedHashSet<>(dependentBeans.length);
                //对依赖 Bean 进行类型检查
                for (String dependentBean : dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                
        }
    }

    //注册完成依赖注入的 Bean
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    return exposedObject;
}

通过对方法源码的分析,看到具体的依赖注入实现在以下两个方法中:

  • createBeanInstance:生成 Bean 所包含的 java 对象实例。
  • populateBean :对 Bean 属性的依赖注入进行处理。

3)createBeanInstance 方法创建 Bean 的 java 实例对象

在 createBeanInstance 方法中,根据指定的初始化策略,使用静态工厂、工厂方法或者容器的自动装配特性生成 java 实例对象,创建对象的源码如下:

protected BeanWrapper createBeanInstance(String beanName,
                                         RootBeanDefinition mbd,
                                         @Nullable Object[] args) {
    //检查确认 Bean 是可实例化的
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

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

    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }
	//调用工厂方法实例化
    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    //使用容器的自动装配方法进行实例化
    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) {
            //配置了自动装配属性,使用容器的自动装配实例化
			//容器的自动装配是根据参数类型匹配 Bean 的构造方法
            return autowireConstructor(beanName, mbd, null, null);
        }
        else {
            //使用默认的无参构造方法实例化
            return instantiateBean(beanName, mbd);
        }
    }

    //使用 Bean 的构造方法进行实例化
    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);
    }

    //使用默认的无参构造方法实例化
    return instantiateBean(beanName, mbd);
}
protected BeanWrapper instantiateBean(final String beanName,
                                      final RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        final BeanFactory parent = this;
        //获取系统的安全管理接口,JDK 标准的安全管理 API
        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;
    }
}
//使用初始化策略实例化 Bean 对象
public Object instantiate(RootBeanDefinition bd,
                          @Nullable String beanName,
                          BeanFactory owner) {
    //如果 Bean 定义中没有方法覆盖,则就不需要 CGLIB 父类类的方法
    if (!bd.hasMethodOverrides()) {
        Constructor<?> constructorToUse;
        synchronized (bd.constructorArgumentLock) {
            //获取对象的构造方法或工厂方法
            constructorToUse = 
                (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
            //如果没有构造方法且没有工厂方法
            if (constructorToUse == null) {
                //使用 JDK 的反射机制,判断要实例化的 Bean 是否是接口
                final Class<?> clazz = bd.getBeanClass();
                if (clazz.isInterface()) {
                    throw new BeanInstantiationException(clazz,
                               	"Specified class is an interface");
                }
                try {
                    //使用反射机制获取 Bean 的构造方法
                    if (System.getSecurityManager() != null) {
                        constructorToUse = AccessController.doPrivileged(
                            (PrivilegedExceptionAction<Constructor<?>>) 
                            		clazz::getDeclaredConstructor);
                    }
                    else {
                        constructorToUse = clazz.getDeclaredConstructor();
                    }
                    bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                }
               
            }
        }
        //使用 BeanUtils 实例化,通过反射机制调用”构造方法.newInstance(arg)”来进行实例化
        return BeanUtils.instantiateClass(constructorToUse);
    }
    else {
        //使用 CGLIB 来实例化对象
        return instantiateWithMethodInjection(bd, beanName, owner);
    }
}

如果 Bean 有方法被覆盖了,则使用 JDK 的反射机制进行实例化,否则,使用 CGLIB 进行实例化。

//使用 CGLIB 进行 Bean 对象实例化
public Object instantiate(@Nullable Constructor<?> ctor,
                          Object... args) {
    
    Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
    Object instance;
    if (ctor == null) {
        instance = BeanUtils.instantiateClass(subclass);
    }
    else {
        //CGLIB 中的类,生成实例对象
        try {
            Constructor<?> enhancedSubclassConstructor = 	
                		subclass.getConstructor(ctor.getParameterTypes());
            instance = enhancedSubclassConstructor.newInstance(args);
        }
        
    }
    // SPR-10785: set callbacks directly on the instance instead of in the
    // enhanced class (via the Enhancer) in order to avoid memory leaks.
    Factory factory = (Factory) instance;
    factory.setCallbacks(
        new Callback[] {NoOp.INSTANCE,
                        new LookupOverrideMethodInterceptor(
                            this.beanDefinition, this.owner),
            			new ReplaceOverrideMethodInterceptor(
                            this.beanDefinition, this.owner)});
    return instance;
}

JDK 的动态代理只能针对接口,如果一个类没有实现任何接口,要对其进行动态代理只能使用 CGLIB。

4)populateBean 方法对 Bean 属性的依赖注入进行处理

生成对象后,Spring IOC 容器是如何将 Bean 的属性依赖关系注入 Bean 实例对象中并设置好的,属性依赖注入的代码如下:

//将 Bean 属性设置到生成的实例对象上
protected void populateBean(String beanName,
                            RootBeanDefinition mbd,
                            @Nullable BeanWrapper bw) {


    boolean continueWithPropertyPopulation = true;
	//在设置属性之前调用 Bean 的 PostProcessor 后置处理器
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = 
                    		(InstantiationAwareBeanPostProcessor) bp;
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(),
                                                       beanName)) {
                    continueWithPropertyPopulation = false;
                    break;
                }
            }
        }
    }

    if (!continueWithPropertyPopulation) {
        return;
    }
	//获取容器在解析 Bean 定义资源时为 BeanDefiniton 中设置的属性值
    PropertyValues pvs = (mbd.hasPropertyValues() ?
                          		mbd.getPropertyValues() : null);
	//依赖注入开始,首先处理 autowire 自动装配的注入
    if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME
        || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        //对 autowire 自动装配的处理,根据 Bean 名称自动装配注入
        if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        //根据 Bean 类型自动装配注入
        if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }
	//检查容器是否持有用于处理单例模式 Bean 关闭时的后置处理器
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    boolean needsDepCheck = (mbd.getDependencyCheck() != 
                             AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

    PropertyDescriptor[] filteredPds = null;
    //Bean 实例对象没有依赖,即没有继承基类
    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);
    }
}
//解析并注入依赖属性的过程
protected void applyPropertyValues(String beanName, 
                                   BeanDefinition mbd, 
                                   BeanWrapper bw, 
                                   PropertyValues pvs) {
    if (pvs.isEmpty()) {
        return;
    }
	//封装属性值
    if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
        //设置安全上下文,JDK 安全机制
        ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
    }

    MutablePropertyValues mpvs = null;
    List<PropertyValue> original;

    if (pvs instanceof MutablePropertyValues) {
        mpvs = (MutablePropertyValues) pvs;
        //属性值已经转换
        if (mpvs.isConverted()) {
            //为实例化对象设置属性值
            try {
                bw.setPropertyValues(mpvs);
                return;
            }
        }
        //获取属性值对象的原始类型值
        original = mpvs.getPropertyValueList();
    }
    else {
        original = Arrays.asList(pvs.getPropertyValues());
    }
	//获取用户自定义的类型转换
    TypeConverter converter = getCustomTypeConverter();
    if (converter == null) {
        converter = bw;
    }
    //创建一个 Bean 定义属性值解析器,
    //将 Bean 定义中的属性值解析为 Bean 实例对象的实际值
    BeanDefinitionValueResolver valueResolver = 
        new BeanDefinitionValueResolver(this, beanName, mbd, converter);

    //为属性的解析值创建一个拷贝,将拷贝的数据注入到实例对象中
    List<PropertyValue> deepCopy = new ArrayList<>(original.size());
    boolean resolveNecessary = false;
    for (PropertyValue pv : original) {
        //属性值不需要转换
        if (pv.isConverted()) {
            deepCopy.add(pv);
        }
        //属性值需要转换
        else {
            String propertyName = pv.getName();
            //原始的属性值,即转换之前的属性值
            Object originalValue = pv.getValue();
            //转换属性值,例如将引用转换为 IOC 容器中实例化对象引用
            Object resolvedValue = 
                valueResolver.resolveValueIfNecessary(pv, originalValue);
            //转换之后的属性值
            Object convertedValue = resolvedValue;
            //属性值是否可以转换
            boolean convertible = bw.isWritableProperty(propertyName)
                && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
            if (convertible) {
                //使用用户自定义的类型转换器转换属性值
                convertedValue = 
                    convertForProperty(resolvedValue, propertyName, bw, converter);
            }
            //存储转换后的属性值,避免每次属性注入时的转换工作
            if (resolvedValue == originalValue) {
                if (convertible) {
                    //设置属性转换之后的值
                    pv.setConvertedValue(convertedValue);
                }
                deepCopy.add(pv);
            }
            //属性是可转换的,且属性原始值是字符串类型,
            //且属性的原始类型值不是动态生成的字符串,且属性的原始值不是集合或者数组类型
            else if (convertible 
                     && originalValue instanceof TypedStringValue 
                     && !((TypedStringValue) originalValue).isDynamic()
                     && !(convertedValue instanceof Collection
                          || ObjectUtils.isArray(convertedValue))) {
                pv.setConvertedValue(convertedValue);
                deepCopy.add(pv);
            }
            else {
                resolveNecessary = true;
                //重新封装属性的值
                deepCopy.add(new PropertyValue(pv, convertedValue));
            }
        }
    }
    if (mpvs != null && !resolveNecessary) {
        //标记属性值已经转换过
        mpvs.setConverted();
    }
	//进行属性依赖注入
    try {
        bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    }
}

分析上述代码,可以看出对属性的注入过程分以下两种情况:

  • 属性值类型不需要转换时,不需要解析属性值,直接准备进行依赖注入。
  • 属性值需要进行类型转换时,如对其他对象的引用等,首先需要解析属性值,然后对解析后的属性
    值进行依赖注入。

对属性值的解析是在 BeanDefinitionValueResolver 类中的 resolveValueIfNecessary 方法中进行的,对属性值的依赖注入是通过 bw.setPropertyValues 方法实现的,在分析属性值的依赖注入之前,先分析一下对属性值的解析过程。

5)BeanDefinitionValueResolver 解析属性值:

当容器在对属性进行依赖注入时,如果发现属性值需要进行类型转换,如属性值是容器中另一个 Bean实例对象的引用,则容器首先需要根据属性值解析出所引用的对象,然后才能将该引用对象注入到目标实例对象的属性上去,对属性进行解析的由 resolveValueIfNecessary 方法实现,其源码如下:

//解析属性值,对注入类型进行转换
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
    //对引用类型的属性进行解析
    if (value instanceof RuntimeBeanReference) {
        RuntimeBeanReference ref = (RuntimeBeanReference) value;
        //调用引用类型属性的解析方法
        return resolveReference(argName, ref);
    }
    //对属性值是引用容器中另一个 Bean 名称的解析
    else if (value instanceof RuntimeBeanNameReference) {
        String refName = ((RuntimeBeanNameReference) value).getBeanName();
        refName = String.valueOf(doEvaluate(refName));
        //从容器中获取指定名称的 Bean
        if (!this.beanFactory.containsBean(refName)) {
            throw new BeanDefinitionStoreException(
                "Invalid bean name '" + refName +
                "' in bean reference for " + argName);
        }
        return refName;
    }
    //对 Bean 类型属性的解析,主要是 Bean 中的内部类
    else if (value instanceof BeanDefinitionHolder) {
        BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
        return resolveInnerBean(argName, 
                                bdHolder.getBeanName(), 
                                bdHolder.getBeanDefinition());
    }
    else if (value instanceof BeanDefinition) {
        BeanDefinition bd = (BeanDefinition) value;
        String innerBeanName = "(inner bean)"
            + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR
            + ObjectUtils.getIdentityHexString(bd);
        return resolveInnerBean(argName, innerBeanName, bd);
    }
    //对集合数组类型的属性解析
    else if (value instanceof ManagedArray) {
        //获取数组的类型
        ManagedArray array = (ManagedArray) value;
        Class<?> elementType = array.resolvedElementType;
        if (elementType == null) {
            //获取数组元素的类型
            String elementTypeName = array.getElementTypeName();
            if (StringUtils.hasText(elementTypeName)) {
                try {
                    //使用反射机制创建指定类型的对象
                    elementType = ClassUtils.forName(elementTypeName, 
                                           this.beanFactory.getBeanClassLoader());
                    array.resolvedElementType = elementType;
                }
            }
            //没有获取到数组的类型,也没有获取到数组元素的类型
			//则直接设置数组的类型为 Object
            else {
                elementType = Object.class;
            }
        }
        //创建指定类型的数组
        return resolveManagedArray(argName, (List<?>) value, elementType);
    }
    //解析 list 类型的属性值
    else if (value instanceof ManagedList) {
        // May need to resolve contained runtime references.
        return resolveManagedList(argName, (List<?>) value);
    }
    //解析 set 类型的属性值
    else if (value instanceof ManagedSet) {
        // May need to resolve contained runtime references.
        return resolveManagedSet(argName, (Set<?>) value);
    }
    //解析 map 类型的属性值
    else if (value instanceof ManagedMap) {
        // May need to resolve contained runtime references.
        return resolveManagedMap(argName, (Map<?, ?>) value);
    }
    //解析 props 类型的属性值,props 其实就是 key 和 value 均为字符串的 map
    else if (value instanceof ManagedProperties) {
        Properties original = (Properties) value;
        //创建一个拷贝,用于作为解析后的返回值
        Properties copy = new Properties();
        original.forEach((propKey, propValue) -> {
            if (propKey instanceof TypedStringValue) {
                propKey = evaluate((TypedStringValue) propKey);
            }
            if (propValue instanceof TypedStringValue) {
                propValue = evaluate((TypedStringValue) propValue);
            }
            if (propKey == null || propValue == null) {
                throw new BeanCreationException(
                    this.beanDefinition.getResourceDescription(), this.beanName,
                    "Error converting Properties key/value pair for " + argName 
                    + ": resolved to null");
            }
            copy.put(propKey, propValue);
        });
        return copy;
    }
    //解析字符串类型的属性值
    else if (value instanceof TypedStringValue) {
        TypedStringValue typedStringValue = (TypedStringValue) value;
        Object valueObject = evaluate(typedStringValue);
        try {
            //获取属性的目标类型
            Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
            if (resolvedTargetType != null) {
                //对目标类型的属性进行解析,递归调用
                return this.typeConverter.convertIfNecessary(valueObject, 
                                                             resolvedTargetType);
            }
            //没有获取到属性的目标对象,则按 Object 类型返回
            else {
                return valueObject;
            }
        }
        ...
    }
    else if (value instanceof NullBean) {
        return null;
    }
    else {
        return evaluate(value);
    }
}
//解析引用类型的属性值
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
		try {
			Object bean;
            //获取引用的 Bean 名称
			String refName = ref.getBeanName();
			refName = String.valueOf(doEvaluate(refName));
            //如果引用的对象在父类容器中,则从父类容器中获取指定的引用对象
			if (ref.isToParent()) {
				...
				bean = this.beanFactory.getParentBeanFactory().getBean(refName);
			}
            //从当前的容器中获取指定的引用 Bean 对象,如果指定的 Bean 没有被实例化
			//则会递归触发引用 Bean 的初始化和依赖注入
			else {
				bean = this.beanFactory.getBean(refName);
                //将当前实例化对象的依赖引用对象
				this.beanFactory.registerDependentBean(refName, this.beanName);
			}
			if (bean instanceof NullBean) {
				bean = null;
			}
			return bean;
		}
	}

6)AbstractNestablePropertyAccessor对 Bean 属性的依赖注入

AbstractNestablePropertyAccessor 类主要是对容器中完成初始化的 Bean 实例对象进行属性的依赖注入,即把 Bean 对象设置到它所依赖的另一个 Bean 的属性中去,依赖注入的相关源码如下:

//实现属性依赖注入功能
protected void setPropertyValue(PropertyTokenHolder tokens,
                                PropertyValue pv) throws BeansException {
    	//keys 是用来保存集合类型属性的 size
		if (tokens.keys != null) {
            //对集合类型的属性注入
			processKeyedProperty(tokens, pv);
		}
		else {
            //对非集合类型的属性注入
			processLocalProperty(tokens, pv);
		}
	}
//对集合类型的属性注入
private void processKeyedProperty(PropertyTokenHolder tokens,
                                  PropertyValue pv) {
    //获取属性值,该方法内部使用 JDK 的内省( Introspector)机制
	//调用属性的 getter(readerMethod)方法,获取属性的值
    Object propValue = getPropertyHoldingValue(tokens);
    PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);
    ...
    //获取集合类型属性的长度
    String lastKey = tokens.keys[tokens.keys.length - 1];
	//注入 array 类型的属性值
    if (propValue.getClass().isArray()) {
        //获取数组的类型
        Class<?> requiredType = propValue.getClass().getComponentType();
        //获取数组的长度
        int arrayIndex = Integer.parseInt(lastKey);
        Object oldValue = null;
        try {
            //获取数组以前初始化的值
            if (isExtractOldValueForEditor() 
                && arrayIndex < Array.getLength(propValue)) {
                oldValue = Array.get(propValue, arrayIndex);
            }
            //将属性的值赋值给数组中的元素
            Object convertedValue = convertIfNecessary(tokens.canonicalName,
                                   oldValue, pv.getValue(),
                                   requiredType, ph.nested(tokens.keys.length));
            int length = Array.getLength(propValue);
            if (arrayIndex >= length && arrayIndex < this.autoGrowCollectionLimit) {
                Class<?> componentType = propValue.getClass().getComponentType();
                Object newArray = Array.newInstance(componentType, arrayIndex + 1);
                System.arraycopy(propValue, 0, newArray, 0, length);
                setPropertyValue(tokens.actualName, newArray);
                propValue = getPropertyValue(tokens.actualName);
            }
            Array.set(propValue, arrayIndex, convertedValue);
        }
    }
	//注入 list 类型的属性值
    else if (propValue instanceof List) {
        Class<?> requiredType = ph.getCollectionType(tokens.keys.length);
        List<Object> list = (List<Object>) propValue;
        int index = Integer.parseInt(lastKey);
        Object oldValue = null;
        if (isExtractOldValueForEditor() && index < list.size()) {
            oldValue = list.get(index);
        }
        //获取 list 解析后的属性值
        Object convertedValue = convertIfNecessary(tokens.canonicalName, 
                               oldValue, pv.getValue(),
                               requiredType, ph.nested(tokens.keys.length));
        int size = list.size();
        //如果 list 的长度大于属性值的长度,则多余的元素赋值为 null
        if (index >= size && index < this.autoGrowCollectionLimit) {
            for (int i = size; i < index; i++) {
                try {
                    list.add(null);
                }
            }
            list.add(convertedValue);
        }
        else {
            try {
                //为 list 属性赋值
                list.set(index, convertedValue);
            }
        }
    }
	//注入 map 类型的属性值
    else if (propValue instanceof Map) {
        //获取 map 集合 key 的类型
        Class<?> mapKeyType = ph.getMapKeyType(tokens.keys.length);
        //获取 map 集合 value 的类型
        Class<?> mapValueType = ph.getMapValueType(tokens.keys.length);
        Map<Object, Object> map = (Map<Object, Object>) propValue;
        TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(mapKeyType);
        //解析 map 类型属性 key 值
        Object convertedMapKey = 
            convertIfNecessary(null, null, lastKey, mapKeyType, typeDescriptor);
        Object oldValue = null;
        if (isExtractOldValueForEditor()) {
            oldValue = map.get(convertedMapKey);
        }
        //解析 map 类型属性 value 值
        Object convertedMapValue = convertIfNecessary(
            		tokens.canonicalName, oldValue, pv.getValue(),
                    mapValueType, ph.nested(tokens.keys.length));
        //将解析后的 key 和 value 值赋值给 map 集合属性
        map.put(convertedMapKey, convertedMapValue);
    }
}
//对非集合类型的属性注入
private void processLocalProperty(PropertyTokenHolder tokens, PropertyValue pv) {
    PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);
    //无法获取到属性名或者属性没有提供 setter(写方法)方法
    if (ph == null || !ph.isWritable()) {
        //如果属性值是可选的,即不是必须的,则忽略该属性值
        if (pv.isOptional()) {
            return;
        }
        else {
            throw createNotWritablePropertyException(tokens.canonicalName);
        }
    }

    Object oldValue = null;
    try {
        Object originalValue = pv.getValue();
        Object valueToApply = originalValue;
        if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
            if (pv.isConverted()) {
                valueToApply = pv.getConvertedValue();
            }
            else {
                if (isExtractOldValueForEditor() && ph.isReadable()) {
                    try {
                        // 读取属性值
                        oldValue = ph.getValue();
                    }
                }
                //设置属性的注入值
                valueToApply = convertForProperty(tokens.canonicalName,
                                 oldValue, originalValue, ph.toTypeDescriptor());
            }
            pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
        }
        // 设置属性值
        ph.setValue(valueToApply);
    }
    catch (TypeMismatchException ex) {
        throw ex;
    }
    catch (InvocationTargetException ex) {
        PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(
            getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
        if (ex.getTargetException() instanceof ClassCastException) {
            throw new TypeMismatchException(propertyChangeEvent, ph.getPropertyType(), ex.getTargetException());
        }
        else {
            Throwable cause = ex.getTargetException();
            if (cause instanceof UndeclaredThrowableException) {
                // May happen e.g. with Groovy-generated methods
                cause = cause.getCause();
            }
            throw new MethodInvocationException(propertyChangeEvent, cause);
        }
    }
    catch (Exception ex) {
        PropertyChangeEvent pce = new PropertyChangeEvent(
            getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
        throw new MethodInvocationException(pce, ex);
    }
}
// 获取属性值
public Object getValue() throws Exception {
    //获取属性的 getter 方法(读方法),JDK 内省机制
    final Method readMethod = this.pd.getReadMethod();
    if (System.getSecurityManager() != null) {
        //如果属性的 getter 方法不是 public 访问控制权限的,即访问控制权限比较严格,
		//则使用 JDK 的反射机制强行访问非 public 的方法(暴力读取属性值)
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            //根据权限修改属性的读取控制限制
            ReflectionUtils.makeAccessible(readMethod);
            return null;
        });
        //属性没有提供 getter 方法时,调用潜在的读取属性值的方法,获取属性值
        try {
            return AccessController.doPrivileged(
                (PrivilegedExceptionAction<Object>) () 
                -> readMethod.invoke(getWrappedInstance(),
                                     (Object[]) null), acc);
        }
        catch (PrivilegedActionException pae) {
            throw pae.getException();
        }
    }
    else {
        ReflectionUtils.makeAccessible(readMethod);
        return readMethod.invoke(getWrappedInstance(), (Object[]) null);
    }
}
//设置属性值
public void setValue(final @Nullable Object value) throws Exception {
    //根据 JDK 的内省机制,获取属性的 setter(写方法)方法
    final Method writeMethod = 
        (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
                    ((GenericTypeAwarePropertyDescriptor) 
                        this.pd).getWriteMethodForActualAccess() :
                    this.pd.getWriteMethod());
    if (System.getSecurityManager() != null) {
        //如果属性的 setter 方法是非 public,即访问控制权限比较严格,则使用 JDK 的反射机制,
		//强行设置 setter 方法可访问(暴力为属性赋值)
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            ReflectionUtils.makeAccessible(writeMethod);
            return null;
        });
        //将属性值设置到属性上去
        try {
            AccessController.doPrivileged(
                (PrivilegedExceptionAction<Object>) () 
                   -> writeMethod.invoke(getWrappedInstance(), value), acc);
        }
        catch (PrivilegedActionException ex) {
            throw ex.getException();
        }
    }
    else {
        ReflectionUtils.makeAccessible(writeMethod);
        writeMethod.invoke(getWrappedInstance(), value);
    }
}

通过对上面注入依赖代码的分析,明白了 Spring IOC 容器是如何将属性的值注入到 Bean 实例对象中去的:

  • 对于集合类型的属性,将其属性值解析为目标类型的集合后直接赋值给属性。
  • 对于非集合类型的属性,大量使用了 JDK 的反射和内省机制,通过属性的 getter 方法(reader method)获取指定属性注入以前的值,同时调用属性的 setter 方法(writer method)为属性设置注入后的值。看到这里相信很多人都明白了 Spring 的 setter 注入原理。

至此 Spring IOC 容器对 Bean 定义资源文件的**定位,载入、解析和依赖注入**已经全部分析完毕,现在Spring IOC 容器中管理了一系列靠依赖关系联系起来的 Bean,程序不需要应用自己手动创建所需的对象,Spring IOC 容器会在我们使用的时候自动为我们创建,并且为我们注入好相关的依赖,这就是Spring 核心功能的控制反转和依赖注入的相关功能。

2.3.2.2 参数为requiredType

1)resolveBean 获取bean

AbstractBeanFactory 通过 getBean 向 IOC 容器获取被管理的 Bean,getBean(requiredType)代码执行的是DefaultListableBeanFactory 的getBean方法,相关方法的源码如下:

private <T> T resolveBean(ResolvableType requiredType,
                          @Nullable Object[] args,
                          boolean nonUniqueAsNull) {
    //实际bean的创建是由resolveNameBean完成的
    NamedBeanHolder<T> namedBean = 
        resolveNamedBean(requiredType, args, nonUniqueAsNull);
    if (namedBean != null) {
        return namedBean.getBeanInstance();
    }
    
    BeanFactory parent = getParentBeanFactory();
    if (parent instanceof DefaultListableBeanFactory) {
        return ((DefaultListableBeanFactory) parent)
            .resolveBean(requiredType, args, nonUniqueAsNull);
    }
    else if (parent != null) {
        ObjectProvider<T> parentProvider = parent.getBeanProvider(requiredType);
        if (args != null) {
            return parentProvider.getObject(args);
        }
        else {
            return (nonUniqueAsNull 
                    ? parentProvider.getIfUnique()
                    : parentProvider.getIfAvailable());
        }
    }
    return null;
}
private <T> NamedBeanHolder<T> resolveNamedBean(
                            ResolvableType requiredType, 
                            @Nullable Object[] args, 
                            boolean nonUniqueAsNull) throws BeansException {
    // 根据类型得到候选的beanNames
    String[] candidateNames = getBeanNamesForType(requiredType);

    // 筛选是否自动注入的bean
    if (candidateNames.length > 1) {
        List<String> autowireCandidates = new ArrayList<>(candidateNames.length);
        for (String beanName : candidateNames) {
            if (!containsBeanDefinition(beanName) 
                || getBeanDefinition(beanName).isAutowireCandidate()) {
                autowireCandidates.add(beanName);
            }
        }
        if (!autowireCandidates.isEmpty()) {
            candidateNames = StringUtils.toStringArray(autowireCandidates);
        }
    }

    if (candidateNames.length == 1) {
        String beanName = candidateNames[0];
        // bean实例化
        return new NamedBeanHolder<>(beanName, 
                              (T) getBean(beanName, requiredType.toClass(), args));
    }
    else if (candidateNames.length > 1) {
        Map<String, Object> candidates = new LinkedHashMap<>(candidateNames.length);
        for (String beanName : candidateNames) {
            if (containsSingleton(beanName) && args == null) {
                Object beanInstance = getBean(beanName);
                candidates.put(beanName, 
                         (beanInstance instanceof NullBean ? null : beanInstance));
            }
            else {
                candidates.put(beanName, getType(beanName));
            }
        }
        String candidateName = 
            determinePrimaryCandidate(candidates, requiredType.toClass());
        if (candidateName == null) {
            candidateName = 
                determineHighestPriorityCandidate(candidates, requiredType.toClass());
        }
        if (candidateName != null) {
            Object beanInstance = candidates.get(candidateName);
            if (beanInstance == null || beanInstance instanceof Class) {
                beanInstance = getBean(candidateName, requiredType.toClass(), args);
            }
            return new NamedBeanHolder<>(candidateName, (T) beanInstance);
        }
    }
    return null;
}

这里分成两步:

  • getBeanNamesForType 根据类型获取所有满足类型要求的beanName

  • 从这些bean名称中筛选出满足的一个,有三种策略:

    • 自动注入类型
    • determinePrimaryCandidate
    • determineHighestPriorityCandidate

2)getBeanNamesForType 获取满足要求的bean名称

getBeanNamesForType 方法调用的是doGetBeanNamesForType方法,源码如下:

private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
    List<String> result = new ArrayList<>();

    // Check all bean definitions.
    for (String beanName : this.beanDefinitionNames) {
        // beanName不是别名
        if (!isAlias(beanName)) {
            try {
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                //mbd.isAbstract()判断这个类是不是抽象类 默认是false
                //allowEagerInit  是否允许提前初始化 这个值是传入的值
                //mbd.hasBeanClass()  是否已经有BeanClass了
                //mbd.isLazyInit()是否允许延迟初始化 默认false
                //isAllowEagerClassLoading() 是否允许提前加载(全局变量)
                //requiresEagerInitForType 检查特殊的Bean是否需要提前被初始化
                if (!mbd.isAbstract()
                    && (allowEagerInit
                        ||(mbd.hasBeanClass() 
                           || !mbd.isLazyInit() 
                           || isAllowEagerClassLoading())
                        && !requiresEagerInitForType(mbd.getFactoryBeanName()))) {
                    boolean isFactoryBean = isFactoryBean(beanName, mbd);
                    BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
                    // 这个地方是判断是不是找到匹配的beanName 这里关键的是isTypeMatch这个方法
                    // 在这个方法中会导致一些FactoryBean被提前实例化 
                    // 所以这里给我们的一个提示是:在Spring容器的启动阶段,
                    // 调用isTypeMatch这个方法去判断Bean的类型的时候要慎重一些。
                    boolean matchFound =
                        (allowEagerInit || !isFactoryBean
                             || (dbd != null && !mbd.isLazyInit()) 
                             || containsSingleton(beanName)) 
                        && (includeNonSingletons
                             || (dbd != null ? mbd.isSingleton() : 
                                 isSingleton(beanName))) 
                        && isTypeMatch(beanName, type);
                    //如果类型不匹配 并且还是FactoryBean类型的BeanDefinition
                    if (!matchFound && isFactoryBean) {
                        //这里将beanName变为&beanName
                        beanName = FACTORY_BEAN_PREFIX + beanName;
                        matchFound = (includeNonSingletons || mbd.isSingleton())
                            && isTypeMatch(beanName, type);
                    }
                    //如果类型相匹配的话 则将beanName放入到结果集中
                    if (matchFound) {
                        result.add(beanName);
                    }
                }
            }
        }
    }
}
public boolean isTypeMatch(String name, ResolvableType typeToMatch)
    							throws NoSuchBeanDefinitionException {
    // 这里是对beanName进行转换
    // 如:如果传入的beanName是&beanName,则将&去掉。
    // 如果传入的beanName有别名的话,则替换为别名
    String beanName = transformedBeanName(name);
    
    // 根据beanName获取bean的实例
    // 前提是其对应的bean已经被实例化了 或者正在实例化中
    Object beanInstance = getSingleton(beanName, false);
    if (beanInstance != null && beanInstance.getClass() != NullBean.class) {
        //如果是FactoryBean类型的实例
        if (beanInstance instanceof FactoryBean) {
            //是否要获取在FactoryBean中创建的Bean实例
            if (!BeanFactoryUtils.isFactoryDereference(name)) {
                //这里是调用FactoryBean的getObjectType方法 来获取bean的类型
                Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance);
                return (type != null && typeToMatch.isAssignableFrom(type));
            }
            else {
                //直接获取FactoryBean类型的实例
                return typeToMatch.isInstance(beanInstance);
            }
        }
        //是否要获取在FactoryBean中创建的Bean实例
        else if (!BeanFactoryUtils.isFactoryDereference(name)) {
            //如果beanName不是以&开头 则直接进行类型比较
            if (typeToMatch.isInstance(beanInstance)) {
                // Direct match for exposed instance?
                return true;
            }
            //泛型的处理
            else if (typeToMatch.hasGenerics() && containsBeanDefinition(beanName)) {
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                Class<?> targetType = mbd.getTargetType();
                if (targetType != null 
                    && targetType != ClassUtils.getUserClass(beanInstance)) {
                    Class<?> classToMatch = typeToMatch.resolve();
                    if (classToMatch != null 
                        && !classToMatch.isInstance(beanInstance)) {
                        return false;
                    }
                    if (typeToMatch.isAssignableFrom(targetType)) {
                        return true;
                    }
                }
                ResolvableType resolvableType = mbd.targetType;
                if (resolvableType == null) {
                    resolvableType = mbd.factoryMethodReturnType;
                }
                return (resolvableType != null
                        && typeToMatch.isAssignableFrom(resolvableType));
            }
        }
        return false;
    }
    else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
        // null instance registered
        return false;
    }
    //这里是从父BeanFactory中进行查找匹配 查找匹配的过程是一样的。
    BeanFactory parentBeanFactory = getParentBeanFactory();
    if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
        return parentBeanFactory.isTypeMatch(originalBeanName(name), typeToMatch);
    }

    // 根据beanName重新检索BeanDefinition 这里返回一个RootBeanDefinition
    // 如果父子容器中存在相同类型的bean会进行合并
    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

    Class<?> classToMatch = typeToMatch.resolve();
    if (classToMatch == null) {
        classToMatch = FactoryBean.class;
    }
    // 如果传入的class类型为FactoryBean类型
    // 则直接返回FactoryBean类型的数组
    // 否则会将传入的class的类型和FactoryBean组装在一起
    Class<?>[] typesToMatch = (FactoryBean.class == classToMatch
                               ? new Class<?>[] {classToMatch}
                               : new Class<?>[] {FactoryBean.class, classToMatch});
    // 这个地方是获取最原始的BeanDefinition
    // 不是组装之后的 RootBeanDefinition
    BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
    if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
        RootBeanDefinition tbd = 
            getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
        //这里是取BeanDefinition中的bean类型
        Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd, typesToMatch);
        if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
            return typeToMatch.isAssignableFrom(targetClass);
        }
    }
    // 获取目标类型 通常是去BeanDefinition中的resolvedTargetType
    Class<?> beanType = predictBeanType(beanName, mbd, typesToMatch);
    if (beanType == null) {
        return false;
    }
    // 如果BeanDefinition中的beanType是FactoryBean类型
    if (FactoryBean.class.isAssignableFrom(beanType)) {
        if (!BeanFactoryUtils.isFactoryDereference(name) && beanInstance == null) {
            //这个地方 会将FactoryBean类型的Bean进行实例化
            beanType = getTypeForFactoryBean(beanName, mbd);
            if (beanType == null) {
                return false;
            }
        }
    }
    else if (BeanFactoryUtils.isFactoryDereference(name)) {
        beanType = predictBeanType(beanName, mbd, FactoryBean.class);
        if (beanType == null || !FactoryBean.class.isAssignableFrom(beanType)) {
            return false;
        }
    }

    ResolvableType resolvableType = mbd.targetType;
    if (resolvableType == null) {
        //工厂方法创建的Bean
        resolvableType = mbd.factoryMethodReturnType;
    }
    if (resolvableType != null && resolvableType.resolve() == beanType) {
        return typeToMatch.isAssignableFrom(resolvableType);
    }
    return typeToMatch.isAssignableFrom(beanType);
}

isTypeMatch这个方法就是进行各种Bean类型的判断,如是已经实例化的FactoryBean可能会调用它的getObjectType方法获取Bean的类型,或者从BeanDefinition中获取Bean的类型,并且如果是未实例化的FactoryBean,为了**进行Bean类型的判断会导致FactoryBean的实例化**。

3)determinePrimaryCandidate 策略筛选

protected boolean isPrimary(String beanName, Object beanInstance) {
    if (containsBeanDefinition(beanName)) {
        return getMergedLocalBeanDefinition(beanName).isPrimary();
    }
    BeanFactory parent = getParentBeanFactory();
    return (parent instanceof DefaultListableBeanFactory &&
            ((DefaultListableBeanFactory) parent).isPrimary(beanName, beanInstance));
}

springboot配置的时候使用了@Primary的注解,然后spring会默认的加载有这个注解的对象。当存在多个对象而且还无法区分默认加载那一个对象的时候就会出现的问题。

4)determineHighestPriorityCandidate 策略筛选

protected String determineHighestPriorityCandidate(
    		Map<String, Object> candidates, Class<?> requiredType) {
    String highestPriorityBeanName = null;
    Integer highestPriority = null;
    for (Map.Entry<String, Object> entry : candidates.entrySet()) {
        String candidateBeanName = entry.getKey();
        Object beanInstance = entry.getValue();
        if (beanInstance != null) {
            // 获取优先级
            Integer candidatePriority = getPriority(beanInstance);
            if (candidatePriority != null) {
                if (highestPriorityBeanName != null) {
                    if (candidatePriority.equals(highestPriority)) {
                        ...
                    }
                    else if (candidatePriority < highestPriority) {
                        highestPriorityBeanName = candidateBeanName;
                        highestPriority = candidatePriority;
                    }
                }
                else {
                    highestPriorityBeanName = candidateBeanName;
                    highestPriority = candidatePriority;
                }
            }
        }
    }
    return highestPriorityBeanName;
}

2.4 IOC 容器的高级特性

通过对 Spring IOC 容器的源码分析,基本上了解了 Spring IOC 容器对 Bean 定义资源的定位、读入和解析过程,同时也清楚了当用户通过 getBean 方法向 IOC 容器获取被管理的 Bean时,IOC 容器对 Bean 进行的初始化和依赖注入过程,这些是 Spring IOC 容器的基本功能特性。

Spring IOC 容器还有一些高级特性,例如:

  • 使用 lazy-init 属性对 Bean 预初始化
  • FactoryBean 产生或者修饰 Bean 对象的生成
  • IOC 容器初始化 Bean 过程中使用 BeanPostProcessor 后置处理器对 Bean 声明周期事件管理
  • IOC 容器的 autowiring 自动装配功能

下面分别简述之。

2.4.1 lazy-init 属性实现预实例化

当 Bean 定义资源的元素中配置了 lazy-init 属性时,容器将会在初始化的时候对所配置的 Bean 进行预实例化,Bean 的依赖注入在容器初始化的时候就已经完成。这样,当应用程序第一次向容器索取被管理的 Bean 时,就不用再初始化和对 Bean 进行依赖注入了,直接从容器中获取已经完成依赖注入的现成 Bean,可以提高应用第一次向容器获取 Bean 的性能。

下面我们通过代码分析容器预实例化的实现过程:

2.4.1.1 refresh 函数载入 Bean 定义

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        
        //调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识
        prepareRefresh();
        
        //告诉子类启动 refreshBeanFactory()方法,
        //Bean 定义资源文件的载入从子类的 refreshBeanFactory()方法启动
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        //为 BeanFactory 配置容器特性,例如类加载器、事件处理器等
        prepareBeanFactory(beanFactory);

        try {
            //为容器的某些子类指定特殊的 BeanPost 事件处理器
            postProcessBeanFactory(beanFactory);

            //调用所有注册的 BeanFactoryPostProcessor 的 Bean
            invokeBeanFactoryPostProcessors(beanFactory);

            //为 BeanFactory 注册 BeanPost 事件处理器.
			//BeanPostProcessor 是 Bean 后置处理器,用于监听容器触发的事件
            registerBeanPostProcessors(beanFactory);

            //初始化信息源,和国际化相关
            initMessageSource();

            //初始化容器事件传播器
            initApplicationEventMulticaster();

            //调用子类的某些特殊 Bean 初始化方法
            onRefresh();

            //为事件传播器注册事件监听器
            registerListeners();

            //初始化所有剩余的单例 Bean
            //这里是对容器 lazy-init 属性进行处理的入口方法
            finishBeanFactoryInitialization(beanFactory);

            //初始化容器的生命周期事件处理器,并发布容器的生命周期事件
            finishRefresh();
        } catch (BeansException ex) {
            //销毁以创建的单态 Bean
            destroyBeans();

            //取消 refresh 操作,重置容器的同步标识
            cancelRefresh(ex);
            throw ex;
        } finally {
            resetCommonCaches();
        }
    }
}

2.4.1.2 finishBeanFactoryInitialization 处理预实例化

//对配置了 lazy-init 属性的 Bean 进行预实例化处理
protected void finishBeanFactoryInitialization(
    						ConfigurableListableBeanFactory beanFactory) {
    //为容器指定一个转换服务(ConversionService)
    //在对某些 Bean 属性进行转换时使用
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME)
        && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, 
                                   ConversionService.class)) {
        beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, 
                                ConversionService.class));
    }

    //为了类型匹配,停止使用临时的类加载器
    beanFactory.setTempClassLoader(null);

    //缓存容器中所有注册的 BeanDefinition 元数据,以防被修改
    beanFactory.freezeConfiguration();

    //对配置了 lazy-init 属性的单态模式 Bean 进行预实例化处理
    beanFactory.preInstantiateSingletons();
}

2.4.1.3 DefaultListableBeanFactory 对配置 lazy-init 属性单态 Bean 的预实例化

public void preInstantiateSingletons() throws BeansException {
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    for (String beanName : beanNames) {
        //获取指定名称的 Bean 定义
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        //Bean 不是抽象的,是单态模式的,且 lazy-init 属性配置为 false
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            //如果指定名称的 bean 是创建容器的 Bean
            if (isFactoryBean(beanName)) {
                //获取的是产生容器对象本身,而不是容器产生的 Bean.
				//调用 getBean 方法,触发容器对 Bean 实例化和依赖注入过程
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof FactoryBean) {
                    final FactoryBean<?> factory = (FactoryBean<?>) bean;
                    //标识是否需要预实例化
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null 
                        		&& factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(
                            (PrivilegedAction<Boolean>)															((SmartFactoryBean<?>) factory)::isEagerInit,
                            getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean 
                                && ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        //调用 getBean 方法,触发容器对 Bean 实例化和依赖注入过程
                        getBean(beanName);
                    }
                }
            }
            else {
                //调用 getBean 方法,触发容器对 Bean 实例化和依赖注入过程
                getBean(beanName);
            }
        }
    }
}

2.4.2 FactoryBean 实现

在 Spring 中,有两个很容易混淆的类:BeanFactory 和 FactoryBean。

  • BeanFactory:Bean 工厂,是一个工厂(Factory),它的作用是管理 Bean,即实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
  • FactoryBean:工厂 Bean,是一个 Bean,作用是产生其他 bean 实例。通常情况下,这种 bean 没有什么特别的要求,仅需要提供一个工厂方法,该方法用来返回其他 bean 实例,bean 无须自己实现工厂模式Spring 容器担任工厂角色;但少数情况下,容器中的 bean 本身就是工厂,其作用是产生其它 bean 实例。

当用户使用容器本身时,可以使用转义字符”&”来得到 FactoryBean 本身,以区别通过 FactoryBean产生的实例对象和 FactoryBean 对象本身。例如:如果 myJndiObject 是一个 FactoryBean,则使用&myJndiObject 得到的是 myJndiObject 对象,而不是myJndiObject 产生出来的对象。

public interface FactoryBean<T> {

    //获取容器管理的对象实例
	@Nullable
	T getObject() throws Exception;

    //获取 Bean 工厂创建的对象的类型
	@Nullable
	Class<?> getObjectType();

	default boolean isSingleton() {
		return true;
	}

}
protected <T> T doGetBean(final String name,
                          @Nullable final Class<T> requiredType,
                          @Nullable final Object[] args,
                          boolean typeCheckOnly) throws BeansException {

    //根据指定的名称获取被管理 Bean 的名称,剥离指定名称中对容器的相关依赖
	//如果指定的是别名,将别名转换为规范的 Bean 名称
    final String beanName = transformedBeanName(name);
    Object bean;

    //先从缓存中取是否已经有被创建过的单态类型的 Bean
	//对于单例模式的 Bean 整个 IOC 容器中只创建一次,不需要重复创建
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        //获取给定 Bean 的实例对象,主要是完成 FactoryBean 的相关处理
		//注意:BeanFactory 是管理容器中 Bean 的工厂,
        //而 FactoryBean 是创建创建对象的工厂 Bean,两者之间有区别
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
    ...
}
//获取给定 Bean 的实例对象,主要是完成 FactoryBean 的相关处理
protected Object getObjectForBeanInstance(
                                Object beanInstance,
                                String name,
                                String beanName,
                                @Nullable RootBeanDefinition mbd) {
	//容器已经得到了 Bean 实例对象,这个实例对象可能是一个普通的 Bean,
    //也可能是一个工厂 Bean,如果是一个工厂 Bean,则使用它创建一个 Bean 实例对象,
    //如果调用本身就想获得一个容器的引用,则指定返回这个工厂 Bean 实例对象
    
    //如果指定的名称是容器的解引用(dereference,即是对象本身而非内存地址),
    //且 Bean 实例也不是创建 Bean 实例对象的工厂 Bean
    if (BeanFactoryUtils.isFactoryDereference(name)) {
        if (beanInstance instanceof NullBean) {
            return beanInstance;
        }
        if (!(beanInstance instanceof FactoryBean)) {
            throw new BeanIsNotAFactoryException(transformedBeanName(name), 
                                                 beanInstance.getClass());
        }
    }

    //如果 Bean 实例不是工厂 Bean,或者指定名称是容器的解引用,
	//调用者向获取对容器的引用,则直接返回当前的 Bean 实例
    if (!(beanInstance instanceof FactoryBean)
        || BeanFactoryUtils.isFactoryDereference(name)) {
        return beanInstance;
    }

    //处理指定名称不是容器的解引用,或者根据名称获取的 Bean 实例对象是一个工厂 Bean
	//使用工厂 Bean 创建一个 Bean 的实例对象
    Object object = null;
    if (mbd == null) {
        //从 Bean 工厂缓存中获取给定名称的 Bean 实例对象
        object = getCachedObjectForFactoryBean(beanName);
    }
    //让 Bean 工厂生产给定名称的 Bean 对象实例
    if (object == null) {
        FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
        //如果从 Bean 工厂生产的 Bean 是单态模式的,则缓存
        if (mbd == null && containsBeanDefinition(beanName)) {
            //从容器中获取指定名称的 Bean 定义,如果继承基类,则合并基类相关属性
            mbd = getMergedLocalBeanDefinition(beanName);
        }
        //如果从容器得到 Bean 定义信息,并且 Bean 定义信息不是虚构的,
		//则让工厂 Bean 生产 Bean 实例对象
        boolean synthetic = (mbd != null && mbd.isSynthetic());
        //调用 FactoryBeanRegistrySupport 类的 getObjectFromFactoryBean 方法,
		//实现工厂 Bean 生产 Bean 对象实例的过程
        object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    }
    return object;
}

Dereference(解引用):一个在 C/C++中应用比较多的术语,在 C++中,”*”是解引用符号,而”&”是引用符号,解引用是指变量指向的是所引用对象的本身数据,而不是引用对象的内存地址。

//Bean 工厂生产 Bean 实例对象
protected Object getObjectFromFactoryBean(FactoryBean<?> factory,
                                          String beanName,
                                          boolean shouldPostProcess) {
    //Bean 工厂是单态模式,并且 Bean 工厂缓存中存在指定名称的 Bean 实例对象
    if (factory.isSingleton() && containsSingleton(beanName)) {
        synchronized (getSingletonMutex()) {
            //直接从 Bean 工厂缓存中获取指定名称的 Bean 实例对象
            Object object = this.factoryBeanObjectCache.get(beanName);
            //Bean 工厂缓存中没有指定名称的实例对象,则生产该实例对象
            if (object == null) {
                //调用 Bean 工厂的 getObject 方法生产指定 Bean 的实例对象
                object = doGetObjectFromFactoryBean(factory, beanName);
                //将生产的实例对象添加到 Bean 工厂缓存中
                this.factoryBeanObjectCache.put(beanName, object);
            }
            return object;
        }
    }
    //调用 Bean 工厂的 getObject 方法生产指定 Bean 的实例对象
    else {
        Object object = doGetObjectFromFactoryBean(factory, beanName);
    }
}
//调用 Bean 工厂的 getObject 方法生产指定 Bean 的实例对象
private Object doGetObjectFromFactoryBean(
    				final FactoryBean<?> factory,
                    final String beanName) throws BeanCreationException {

    Object object;
    try {
        if (System.getSecurityManager() != null) {
            AccessControlContext acc = getAccessControlContext();
            try {
                object = AccessController.doPrivileged(
                    (PrivilegedExceptionAction<Object>) factory::getObject, acc);
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {
            //调用 BeanFactory 接口实现类的创建对象方法
            object = factory.getObject();
        }
    }

    //创建出来的实例对象为 null,返回 NullBean
    if (object == null) {
        // 因为单态对象正在创建而返回,抛入异常
        if (isSingletonCurrentlyInCreation(beanName)) {
            ...
        }
        object = new NullBean();
    }
    return object;
}

FactoryBean 的实现类有非常多,比如:Proxy、RMI、JNDI、ServletContextFactoryBean 等等,FactoryBean
接口为 Spring 容器提供了一个很好的封装机制,具体的 getObject 有不同的实现类根据不同的实现策略来具体提供。

2.4.3 BeanPostProcessor 后置处理器

BeanPostProcessor 后置处理器是 Spring IOC 容器经常使用到的一个特性,这个 Bean 后置处理器是一个监听器,可以监听容器触发的 Bean 声明周期事件。后置处理器向容器注册以后,容器中管理的 Bean就具备了接收 IOC 容器事件回调的能力。BeanPostProcessor 的使用非常简单,只需要提供一个实现接口 BeanPostProcessor 的实现类,然后在Bean 的配置文件中设置即可。

public interface BeanPostProcessor {
	//为在 Bean 的初始化前提供回调入口
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
	//为在 Bean 的初始化之后提供回调入口
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

这两个回调的入口都是和容器管理的 Bean 的生命周期事件紧密相关,可以为用户提供在 Spring IOC 容器初始化 Bean 过程中自定义的处理操作。

1)AbstractAutowireCapableBeanFactory 类对容器生成的 Bean 添加后置处理器

protected Object doCreateBean(final String beanName,
                        final RootBeanDefinition mbd,
                        final @Nullable Object[] args) throws BeanCreationException {
	//创建 Bean 实例对象
    ...
    try {
        //对 Bean 属性进行依赖注入
        populateBean(beanName, mbd, instanceWrapper);
        //在对 Bean 实例对象生成和依赖注入完成以后,
        //开始对 Bean 实例对象进行初始化 ,
        //为 Bean 实例对象应用 BeanPostProcessor 后置处理器
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    
    return exposedObject;
}

2)initializeBean 添加 BeanPostProcessor 后置处理器

//初始容器创建的 Bean 实例对象,为其添加 BeanPostProcessor 后置处理器
protected Object initializeBean(final String beanName,
                                final Object bean,
                                @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    }
    else {
        //为 Bean 实例对象包装相关属性,如名称,类加载器,所属容器等信息
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    //对 BeanPostProcessor 后置处理器的 postProcessBeforeInitialization
	//回调方法的调用,为 Bean 实例初始化前做一些处理
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = 
            applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
    //调用 Bean 实例对象初始化的方法,这个初始化方法是在 Spring Bean 定义配置
    //文件中通过 init-method 属性指定的
    try {
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    //对 BeanPostProcessor 后置处理器的 postProcessAfterInitialization
	//回调方法的调用,为 Bean 实例初始化后做一些处理
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = 
            applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}
//调用 BeanPostProcessor 后置处理器实例对象初始化之前的处理方法
public Object applyBeanPostProcessorsBeforeInitialization(
    	Object existingBean, String beanName) throws BeansException {
    Object result = existingBean;
    //遍历容器为所创建的 Bean 添加的所有 BeanPostProcessor 后置处理器
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        //调用 Bean 实例所有的后置处理中的初始化前处理方法,为 Bean 实例对象在
		//初始化之前做一些自定义的处理操作
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}
//调用 BeanPostProcessor 后置处理器实例对象初始化之后的处理方法
public Object applyBeanPostProcessorsAfterInitialization(
    	Object existingBean, String beanName) throws BeansException {
    Object result = existingBean;
    //遍历容器为所创建的 Bean 添加的所有 BeanPostProcessor 后置处理器
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        //调用 Bean 实例所有的后置处理中的初始化后处理方法,为 Bean 实例对象在
		//初始化之后做一些自定义的处理操作
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

BeanPostProcessor 是一个接口,其初始化前的操作方法和初始化后的操作方法均委托其实现子类来实现,在 Spring 中,BeanPostProcessor 的实现子类非常的多,分别完成不同的操作,如:AOP 面向切面编程的注册通知适配器、Bean 对象的数据校验、Bean 继承属性/方法的合并等等,我们以最简单的 AOP切面织入来简单了解其主要的功能。

举例:AdvisorAdapterRegistrationManager 在 Bean 对象初始化后注册通知适配器

AdvisorAdapterRegistrationManager 是 BeanPostProcessor 的一个实现类,其主要的作用为容器中管理的 Bean 注册一个面向切面编程的通知适配器,以便在 Spring 容器为所管理的 Bean 进行面向切面编程时提供方便,其源码如下:

//为容器中管理的 Bean 注册一个面向切面编程的通知适配器
public class AdvisorAdapterRegistrationManager implements BeanPostProcessor {
	//容器中负责管理切面通知适配器注册的对象
	private AdvisorAdapterRegistry advisorAdapterRegistry = 
        		GlobalAdvisorAdapterRegistry.getInstance();

	public void setAdvisorAdapterRegistry(
        				AdvisorAdapterRegistry advisorAdapterRegistry) {
		this.advisorAdapterRegistry = advisorAdapterRegistry;
	}

	//BeanPostProcessor 在 Bean 对象初始化前的操作
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //没有做任何操作,直接返回容器创建的 Bean 对象
		return bean;
	}

    //BeanPostProcessor 在 Bean 对象初始化后的操作
	@Override
	public Object postProcessAfterInitialization(
        				Object bean, String beanName) throws BeansException {
        //如果容器创建的 Bean 实例对象是一个切面通知适配器,则向容器注册
		if (bean instanceof AdvisorAdapter){
			this.advisorAdapterRegistry.registerAdvisorAdapter((AdvisorAdapter) bean);
		}
		return bean;
	}

}

这些操作是容器初始化 Bean 时自动触发的,不需要认为的干预。

2.4.4 自动装配功能

Spring IOC 容器提供了两种管理 Bean 依赖关系的方式:

  • 显式管理:通过 BeanDefinition 的属性值和构造方法实现 Bean 依赖关系管理。
  • autowiring:Spring IOC 容器的依赖自动装配功能,不需要对 Bean 属性的依赖关系做显式的声明,只需要在配置好 autowiring 属性,IOC 容器会自动使用反射查找属性的类型和名称,然后基于属性的类型或者名称来自动匹配容器中管理的 Bean,从而自动地完成依赖注入。

容器对 Bean 实例对象的属性注入的处理发生在 AbstractAutoWireCapableBeanFactory 类中的 populateBean 方法中,通过程序流程分析 autowiring 的实现原理。

populateBean(String beanName,
                            RootBeanDefinition mbd,
                            @Nullable BeanWrapper bw) {
	...
	//对依赖注入处理,首先处理 autowiring 自动装配的依赖注入
    if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME
        || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        //对 autowire 自动装配的处理,根据 Bean 名称自动装配注入
        if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        //根据 Bean 类型自动装配注入
        if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }
	...
}
//根据名称对属性进行自动依赖注入
protected void autowireByName(
                        String beanName, 
                        AbstractBeanDefinition mbd, 
                        BeanWrapper bw, 
                        MutablePropertyValues pvs) {
	//对 Bean 对象中非简单属性
    //(不是简单继承的对象,如 8 中原始类型,字符串,URL 等都是简单属性)进行处理
    String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
    for (String propertyName : propertyNames) {
        //如果 Spring IOC 容器中包含指定名称的 Bean
        if (containsBean(propertyName)) {
            //调用 getBean 方法向 IoC 容器索取指定名称的 Bean 实例,
            //迭代触发属性的初始化和依赖注入
            Object bean = getBean(propertyName);
            //为指定名称的属性赋予属性值
            pvs.add(propertyName, bean);
            //指定名称属性注册依赖 Bean 名称,进行属性依赖注入
            registerDependentBean(propertyName, beanName);
        }
        else {

        }
    }
}
//根据类型对属性进行自动依赖注入
protected void autowireByType(
                        String beanName, 
                        AbstractBeanDefinition mbd, 
                        BeanWrapper bw,
                        MutablePropertyValues pvs) {
	//获取用户定义的类型转换器
    TypeConverter converter = getCustomTypeConverter();
    if (converter == null) {
        converter = bw;
    }
	//存放解析的要注入的属性
    Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
    //对 Bean 对象中非简单属性
    //(不是简单继承的对象,如 8 中原始类型,字符URL 等都是简单属性)进行处理
    String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
    for (String propertyName : propertyNames) {
        try {
            //获取指定属性名称的属性描述器
            PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
            //不对 Object 类型的属性进行 autowiring 自动依赖注入
            if (Object.class != pd.getPropertyType()) {
                //获取属性的 setter 方法
                MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
                //检查指定类型是否可以被转换为目标对象的类型
                boolean eager = 
                    !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
                //创建一个要被注入的依赖描述
                DependencyDescriptor desc = 
                    new AutowireByTypeDependencyDescriptor(methodParam, eager);
                //根据容器的 Bean 定义解析依赖关系,返回所有要被注入的 Bean 对象
                Object autowiredArgument = 
                    resolveDependency(desc, beanName, autowiredBeanNames, converter);
                if (autowiredArgument != null) {
                    //为属性赋值所引用的对象
                    pvs.add(propertyName, autowiredArgument);
                }
                for (String autowiredBeanName : autowiredBeanNames) {
                    //指定名称属性注册依赖 Bean 名称,进行属性依赖注入
                    registerDependentBean(autowiredBeanName, beanName);
                }
                //释放已自动注入的属性
                autowiredBeanNames.clear();
            }
        }
    }
}

真正实现属性注入的是 DefaultSingletonBeanRegistry 类的registerDependentBean 方法:

//为指定的 Bean 注入依赖的 Bean
public void registerDependentBean(String beanName, 
                                  String dependentBeanName) {
    //处理 Bean 名称,将别名转换为规范的 Bean 名称
    String canonicalName = canonicalName(beanName);

    //先从容器中:bean 名称-->全部依赖 Bean 名称集合找查找给定名称 Bean 的依赖 Bean
    synchronized (this.dependentBeanMap) {
        //获取给定名称 Bean 的所有依赖 Bean 名称
        Set<String> dependentBeans =
            this.dependentBeanMap.computeIfAbsent(
            		canonicalName, k -> new LinkedHashSet<>(8));
        
        //向容器中:bean 名称-->全部依赖 Bean 名称集合添加 Bean 的依赖信息
		//即,将 Bean 所依赖的 Bean 添加到容器的集合中
        if (!dependentBeans.add(dependentBeanName)) {
            return;
        }
    }
	//从容器中:bean 名称-->指定名称 Bean 的依赖 Bean 集合找查找给定名称 Bean 的依赖 Bean
    synchronized (this.dependenciesForBeanMap) {
        Set<String> dependenciesForBean =
            this.dependenciesForBeanMap.computeIfAbsent(
            		dependentBeanName, k -> new LinkedHashSet<>(8));
        dependenciesForBean.add(canonicalName);
    }
}

通过对 autowiring 的源码分析,autowiring 的实现过程:

  • 对 Bean 的属性代调用 getBean 方法,完成依赖 Bean 的初始化和依赖注入。
  • 将依赖 Bean 的属性引用设置到被依赖的 Bean 属性上。
  • 将依赖 Bean 的名称和被依赖 Bean 的名称存储在 IOC 容器的集合中。

Spring IOC 容器的 autowiring 属性自动依赖注入是一个很方便的特性,可以简化开发时的配置,但是凡是都有两面性,自动属性依赖注入也有不足,首先,Bean 的依赖关系在配置文件中无法很清楚地看出来,对于维护造成一定困难。其次,由于自动依赖注入是 Spring 容器自动执行的,容器是不会智能判断的,如果配置不当,将会带来无法预料的后果,所以自动依赖注入特性在使用时还是综合考虑。

你可能感兴趣的:(Spring,专题,spring)