10、Spring 源码学习 ~ Bean 的加载步骤详解(一)

Bean 的加载步骤详解(一)

一、FactoryBean 的使用

一般情况下,Spring 通过反射机制,利用 bean 的 class 属性指定的实现类,来实例化 bean。但假如实例化的 bean 需要配置文件提供大量的信息,这个时候配置文件的灵活方式是受限的,此时采用编码的方式也许可得到一个简单的方案。Spring 为此提供了一个 FactoryBean 的工厂类接口,用户可以通过实现该接口,来定制实例化 bean 的逻辑。

Spring 本生提供了 70 多个 FactoryBean 的实现,而且从 Spring 3.0 开始,FactoryBean 可支持泛型,即接口声明改为 FactoryBean<T> 的形式。如下:

package org.springframework.beans.factory;

import org.springframework.lang.Nullable;

public interface FactoryBean<T> {

	String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

    //返回由 FactoryBean 创建的 bean 实例,如果 isSingleton 返回 true,则该实例会放到 Spring 容器中的单例缓存池中
	@Nullable
	T getObject() throws Exception;

    //返回由 FactoryBean 创建的 bean 类型
	@Nullable
	Class<?> getObjectType();

    //返回 FactoryBean 创建的 bean 实例的作用域,默认是单例 singleton
	default boolean isSingleton() {
		return true;
	}
}

<bean> 中的 class 属性是 FactoryBean 的实现类时,通过 getBean() 方法返回的不是 FactoryBean 本身,而是 FactoryBean#getObject 返回的对象。

示例:

Car.java

package com.luo.spring.guides.helloworld.beanloading.factorybean;

import lombok.Data;
import lombok.ToString;

/**
 * @author : archer
 * @date : Created in 2022/10/28 10:27
 * @description :
 */
@Data
@ToString
public class Car {

    //最大速度
    private int maxSpeed;
    //品牌
    private String brand;
    //价格
    private double price;
}

CarFactoryBean.java

package com.luo.spring.guides.helloworld.beanloading.factorybean;

import org.springframework.beans.factory.FactoryBean;

/**
 * @author : archer
 * @date : Created in 2022/10/28 10:28
 * @description :
 */
public class CarFactoryBean implements FactoryBean<Car> {

    private String carInfo;

    @Override
    public Car getObject() throws Exception {
        Car car = new Car();
        String[] infos = carInfo.split(",");
        car.setBrand(infos[0]);
        car.setMaxSpeed(Integer.parseInt(infos[1]));
        car.setPrice(Double.parseDouble(infos[2]));
        return car;
    }

    @Override
    public Class<?> getObjectType() {
        return Car.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }

    public String getCarInfo() {
        return carInfo;
    }

    //接受逗号分隔符设置属性信息,并且顺序固定是 brand,maxSpeed,price
    public void setCarInfo(String carInfo) {
        this.carInfo = carInfo;
    }
}

facotryBeanTest.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="car" class="com.luo.spring.guides.helloworld.beanloading.factorybean.CarFactoryBean">
        <property name="carInfo" value="超级跑车,400,2000000"/>
    </bean>

</beans>

Main.java

package com.luo.spring.guides.helloworld.beanloading.factorybean;

import com.luo.spring.guides.helloworld.common.TestBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author : archer
 * @date : Created in 2022/10/28 10:49
 * @description :
 */
public class Main {

    public static void main(String[] args) {
        ApplicationContext bf = new ClassPathXmlApplicationContext("beanloading/factorybean/facotryBeanTest.xml");

        //获取 Car 实例
        Car car = (Car) bf.getBean("car");
        System.out.println(car);

        //获取 CarFactoryBean 实例
        CarFactoryBean carFactoryBean = (CarFactoryBean) bf.getBean("&car");
        System.out.println(carFactoryBean.getClass());
    }
}

输出:

Car(maxSpeed=400, brand=超级跑车, price=2000000.0)
class com.luo.spring.guides.helloworld.beanloading.factorybean.CarFactoryBean

二、缓存中获取单例 bean

单例 bean 的加载只会在 Spring 的容器中创建一次,后续再获取是直接从缓存中获取。这里首先是从缓存中加载,不存在再去 singleFactories 中加载。这里 Spring 为了避免循环,它创建 bean 的原则是不等 bean 创建完成,就会将创建 bean 的 ObjectFactory 提早曝光加入到缓存中,一旦下个 bean 创建时需要依赖上个 bean,则直接使用 ObjectFactory。

@Override
@Nullable
public Object getSingleton(String beanName) {
    //参数 true 表示允许早期依赖
    return getSingleton(beanName, true);
}

@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // Quick check for existing instance without full singleton lock
    //检查缓存中是否存在实例
    Object singletonObject = this.singletonObjects.get(beanName);
    //缓存还不存在单例 bean 并且当前正在创建中
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        //判断早期依赖中是否存在实例,有则表示 bean 正在加载
        singletonObject = this.earlySingletonObjects.get(beanName);
        if (singletonObject == null && allowEarlyReference) {
            //不存在并且允许早期依赖,则锁定全局变量并进行处理
            synchronized (this.singletonObjects) {
                // Consistent creation of early reference within full singleton lock
                //双重判断缓存中是否存在实例,防止上层判断完后准备加锁的时候,另一线程已实例化,并放到缓存中了
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    singletonObject = this.earlySingletonObjects.get(beanName);
                    if (singletonObject == null) {
                        //当某些 bean 需要提前初始化的时候,则会调用 addSingleFactory 方法将对应的
                        //ObjectFactory 初始化策略,存储在 singletonFactories中
                        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                        if (singletonFactory != null) {
                            //调用预先设定的 getObject 方法
                            singletonObject = singletonFactory.getObject();
                            //记录在缓存中,earlySingletonObjects 与 singletonFactories 互斥
                            this.earlySingletonObjects.put(beanName, singletonObject);
                            this.singletonFactories.remove(beanName);
                        }
                    }
                }
            }
        }
    }
    return singletonObject;
}

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(singletonFactory, "Singleton factory must not be null");
    synchronized (this.singletonObjects) {
        if (!this.singletonObjects.containsKey(beanName)) {
            this.singletonFactories.put(beanName, singletonFactory);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }
}

名词解释:

  • **singletonObjects:**Map 结构,用于保存 BeanName 和创建 bean 实例之间的关系,beanName -> bean instance;
  • **singletonFactories:**Map 结构,用于保存 BeanName 和创建 bean 实例的工厂之间的关系,beanName -> ObjectFactory;
  • **earlySingletonObjects:**Map 结构,用于保存 BeanName 和创建 bean 实例之间的关系
    • 与 singletonObjects 不同之处在于,当一个单例 bean 被放到里面后,那么当 bean 还在创建过程中时,就可以通过 getBean 方法获取到了,其目的是用来检测循环引用。
  • **registeredSingletons:**Set 结构,用来保存当前所有已注册的单例 beanName;

上述代码大致步骤如下:

  • 1、首先尝试从 singletonObjects 中获取实例
  • 2、若上面获取不到,再尝试从 earlySingletonObjects 中获取实例
  • 3、若还是获取不到并且 allowEarlyReference 为 true (允许循环引用)时,再从 singletonFactories 中获取对应的 ObjectFactory,在调用这个 ObjectFactory 的 getObject 来创建 bean,并放到 earlySingletonObjects 缓存中去,并从 singletonFactories 中 remove 掉这个 ObjectFactory。

三、从 bean 的实例中获取对象

在 getBean 的方法中,getObjectForBeanInstance 是个高频率使用的方法。无论是从缓存中还是根据不同的 scope 策略得到 bean 实例后,首先做的都是调这个方法来检测下正确性,即当前 bean 是否是 FactoryBean 类型的 bean,如果是,则调用对应的 FactoryBean 实例中的 getObject() 作为返回值。

这里返回的只是 bean 最原始的状态。并不一定是我们真正需要的 bean。

如:假如我们需要对工厂 bean 进行处理,这里得到的是工厂 bean 的初始状态,而我们真正需要的是工厂 bean 中定义的 factory-method 方法中返回的 bean。而 getObjectForBeanInstance 就是完成这个工作的。源码如下:

protected Object getObjectForBeanInstance(
    Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

    // Don't let calling code try to dereference the factory if the bean isn't a factory.
    //如果指定的 name 是工厂相关(以 & 为前缀),则进入代码
    if (BeanFactoryUtils.isFactoryDereference(name)) {
        if (beanInstance instanceof NullBean) {
            return beanInstance;
        }
        //beanInstance 不是 FactoryBean 类型,则验证不通过
        if (!(beanInstance instanceof FactoryBean)) {
            throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
        }
        if (mbd != null) {
            mbd.isFactoryBean = true;
        }
        //getBean("&car"); 直接返回 FactoryBean
        return beanInstance;
    }

    // Now we have the bean instance, which may be a normal bean or a FactoryBean.
    // If it's a FactoryBean, we use it to create a bean instance, unless the
    // caller actually wants a reference to the factory.
    //现在这个 beanInstance 可能是普通的 bean 实例或者 FactoryBean 对象,
    //如果是普通的 bean,则直接返回
    if (!(beanInstance instanceof FactoryBean)) {
        return beanInstance;
    }

    //加载 FactoryBean
    Object object = null;
    if (mbd != null) {
        mbd.isFactoryBean = true;
    }
    else {
        //尝试从缓存中加载 bean
        object = getCachedObjectForFactoryBean(beanName);
    }
    if (object == null) {
        // Return bean instance from factory.
        //到这里已经明确知道 beanInstance 一定是 FactoryBean 类型
        FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
        // Caches object obtained from FactoryBean if it is a singleton.
        //containsBeanDefinition 检测 beanDefinitionMap (即所有已加载的类)中检测是否定义了 beanName
        if (mbd == null && containsBeanDefinition(beanName)) {
            //将存储 XML 配置文件的 GernericBeanDefinition 转换为 RootBeanDefinition,
            //如果指定 beanName 是子 Bean 的话,同时会合并父类的相关属性
            mbd = getMergedLocalBeanDefinition(beanName);
        }
        //是否是用户定义的,而不是程序本身定义的
        boolean synthetic = (mbd != null && mbd.isSynthetic());
        //用户自定义的无需后置处理
        object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    }
    return object;
}

上述中主要是做一些功能性的判断检查,大致如下:

  • 1、验证 FactoryBean 的正确性
  • 2、非 FactoryBean 不做任何处理
  • 3、对 bean 进行转换
  • 4、将从 Factory 中解析 bean 的工作委托给 getObjectFromFactoryBean。

即真正核心代码委托给了 getObjectFromFactoryBean,其源码如下:

//shouldPostProcess 为 true,表示需要后置处理
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
    //如果是单例模式
    if (factory.isSingleton() && containsSingleton(beanName)) {
        synchronized (getSingletonMutex()) {
            Object object = this.factoryBeanObjectCache.get(beanName);
            if (object == null) {
                object = doGetObjectFromFactoryBean(factory, beanName);
                // Only post-process and store if not put there already during getObject() call above
                // (e.g. because of circular reference processing triggered by custom getBean calls)
                Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                if (alreadyThere != null) {
                    object = alreadyThere;
                }
                else {
                    if (shouldPostProcess) {
                        if (isSingletonCurrentlyInCreation(beanName)) {
                            // Temporarily return non-post-processed object, not storing it yet..
                            return object;
                        }
                        beforeSingletonCreation(beanName);
                        try {
                            //调用 ObjectFactory 的后处理器
                            object = postProcessObjectFromFactoryBean(object, beanName);
                        }
                        catch (Throwable ex) {
                            throw new BeanCreationException(beanName,
                                                            "Post-processing of FactoryBean's singleton object failed", ex);
                        }
                        finally {
                            afterSingletonCreation(beanName);
                        }
                    }
                    if (containsSingleton(beanName)) {
                        this.factoryBeanObjectCache.put(beanName, object);
                    }
                }
            }
            return object;
        }
    }
    else {
        Object object = doGetObjectFromFactoryBean(factory, beanName);
        if (shouldPostProcess) {
            try {
                //调用 ObjectFactory 的后处理器
                object = postProcessObjectFromFactoryBean(object, beanName);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
            }
        }
        return object;
    }
}

这个方法里的逻辑就是,保证返回的 bean,如果是单例的,就是全局唯一的,同时加了一些缓存以提高性能,而获取真正实例对象的逻辑在 doGetObjectFromFactoryBean 方法中,当 bean 声明为 FactoryBean 类型时,提取 bean 时,提取的并不是 FactoryBean,而是 FactoryBean 中对应的 getObject 方法返回的 bean,doGetObjectFromFactoryBean 正是实现这个功能的,doGetObjectFromFactoryBean 源码如下:

private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, 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 {
            //直接调用 getObject 方法返回
            object = factory.getObject();
        }
    }
    catch (FactoryBeanNotInitializedException ex) {
        throw new BeanCurrentlyInCreationException(beanName, ex.toString());
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
    }

    // Do not accept a null value for a FactoryBean that's not fully
    // initialized yet: Many FactoryBeans just return null then.
    if (object == null) {
        if (isSingletonCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(
                beanName, "FactoryBean which is currently in creation returned null from getObject");
        }
        object = new NullBean();
    }
    return object;
}

处理完 doGetObjectFromFactoryBean 之后,程序还做了一些后置处理,即 shouldPostProcess 为 true 时的逻辑,先看 AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean,源码如下:

@Override
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
    return applyBeanPostProcessorsAfterInitialization(object, beanName);
}

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

对于后处理器的使用,后续会有详细介绍,这里我们先记住 Spring 中获取 bean 的规则:

尽可能保证所有 bean 初始化后,都会调用注册的 BeanPostProcessor#postProcessAfterInitialization 方法进行处理

实际开发过程中,可根据此特性设计自己的业务逻辑。

四、获取单例

上面我们学习了从缓存中获取单例的过程,那如果缓存中不存在已经加载的单例 bean,那就需要从头开始 bean 的加载过程了,而 Spring 中使用 getSingleton 的重载方法实现 bean 的加载过程。

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "Bean name must not be null");
    //全局变量需要加同步锁
    synchronized (this.singletonObjects) {
        //首先检查对应的 bean 是否已经加载过,因为 singleton 模式其实就是复用已创建的 bean
        //故此步骤是必须的
        Object singletonObject = this.singletonObjects.get(beanName);
        //如果为空,才可以进行 singleton 的 bean 的初始化
        if (singletonObject == null) {
            if (this.singletonsCurrentlyInDestruction) {
                throw new BeanCreationNotAllowedException(beanName,
                                                          "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                                                          "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
            }
            beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet<>();
            }
            try {
                //初始化 bean
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            }
            catch (IllegalStateException ex) {
                // Has the singleton object implicitly appeared in the meantime ->
                // if yes, proceed with it since the exception indicates that state.
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    throw ex;
                }
            }
            catch (BeanCreationException ex) {
                if (recordSuppressedExceptions) {
                    for (Exception suppressedException : this.suppressedExceptions) {
                        ex.addRelatedCause(suppressedException);
                    }
                }
                throw ex;
            }
            finally {
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = null;
                }
                afterSingletonCreation(beanName);
            }
            if (newSingleton) {
                //加入缓存
                addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}

//单例创建的前置处理
//记录加载状态,this.singletonsCurrentlyInCreation.add(beanName) 将 正在创建的 bean 记录到缓存中,以便对循环依赖进行检测
protected void beforeSingletonCreation(String beanName) {
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
        throw new BeanCurrentlyInCreationException(beanName);
    }
}

//单例创建的后置处理
//将结果记录至缓存并删除加载 bean 过程中所记录的各种辅助状态
protected void afterSingletonCreation(String beanName) {
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
        throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
    }
}

//
protected void addSingleton(String beanName, Object singletonObject) {
    synchronized (this.singletonObjects) {
        this.singletonObjects.put(beanName, singletonObject);
        this.singletonFactories.remove(beanName);
        this.earlySingletonObjects.remove(beanName);
        this.registeredSingletons.add(beanName);
    }
}

上述代码使用的回调方法,使得程序可以在单例创建的前后做一些准备及处理操作,这些准备包括如下内容:

  • 1、检查缓存是否已经加载过
  • 2、若没有加载,则记录 beanName 的正在加载状态
  • 3、加载单例前记录加载状态
  • 4、通过调用参数传入的 ObjectFactory#getObject 实例化bean
  • 5、加载单例后置处理方法调用
  • 6、将结果记录至缓存并删除加载 bean 过程中所记录的各种辅助状态
  • 7、返回处理结果

上面我们并没有看到真正获取单例 bean 的方法,其真正实现逻辑实是在生成 ObjectFactory 的实例中实现的,如下:

if (mbd.isSingleton()) {
    sharedInstance = getSingleton(beanName, () -> {
        try {
            return createBean(beanName, mbd, args);
        }
        catch (BeansException ex) {
            // Explicitly remove instance from singleton cache: It might have been put there
            // eagerly by the creation process, to allow for circular reference resolution.
            // Also remove any beans that received a temporary reference to the bean.
            destroySingleton(beanName);
            throw ex;
        }
    });
    beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

从上面可以看出,我们需要具体到 createBean 方法中探寻真正创建 bean 的逻辑。

五、准备创建 bean

我们跟踪了很多 Spring 源码后,可以发现一个真正干活的函数,一般是以 do 开头的,我们看下 createBean 方法的具体实现:

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {

    if (logger.isTraceEnabled()) {
        logger.trace("Creating instance of bean '" + beanName + "'");
    }
    RootBeanDefinition mbdToUse = mbd;

    // Make sure bean class is actually resolved at this point, and
    // clone the bean definition in case of a dynamically resolved Class
    // which cannot be stored in the shared merged bean definition.
    //锁定 class,根据设置的 class 属性或者根据 className 来解析 class
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // Prepare method overrides.
    try {
        //验证准备重写(覆盖)的方法
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                                               beanName, "Validation of method overrides failed", ex);
    }

    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        //给 BeanPostProcessors(后置处理器) 一个机会来返回代理(替代真正的实例)
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                                        "BeanPostProcessor before instantiation of bean failed", ex);
    }

    try {
        //真正创建 bean
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }
    catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
        // A previously detected exception with proper bean creation context already,
        // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
        throw ex;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
}

以上代码的具体步骤如下:

  • 1、根据设置的 class 属性或者根据 className 来解析 class
  • 2、对 override 属性进行标记和验证
    • override 属性的作用:Spring 配置中是存在 lookup-method 和 replace-method 的,这两个配置的加载统一存放在 BeanDefinition 中的 methodOverrides 属性里,这里的操作就是针对这两个配置的。
  • 3、应用初始化前的后处理器,解析指定 bean 是否存在初始化前的短路操作
  • 4、创建 bean

1、处理 override 属性

查看 AbstractBeanDefinition#prepareMethodOverrides#prepareMethodOverrides 方法:

public void prepareMethodOverrides() throws BeanDefinitionValidationException {
    // Check that lookup methods exist and determine their overloaded status.
    if (hasMethodOverrides()) {
        
        getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
    }
}

//获取对应类中对应方法名的个数
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
    int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
    if (count == 0) {
        throw new BeanDefinitionValidationException(
            "Invalid method override: no method with name '" + mo.getMethodName() +
            "' on class [" + getBeanClassName() + "]");
    }
    else if (count == 1) {
        //当前类中的方法只有一个,设置重载该方法没有被重载,以便后续调用,可以直接使用找到的方法,并且可以提前对方法存在性进行验证
        //标记 MethodOverride 暂未被重写(覆盖),避免参数类型校验的开销
        // Mark override as not overloaded, to avoid the overhead of arg type checking.
        mo.setOverloaded(false);
    }
}

从这里可以看出 lookup-method 和 replace-method 功能的实现原理,就是在 bean 实例化时,如果检测存在 methodOverrides,就会动态地位当前 bean 生成代理,并使用对应的拦截器为 bean 做增强处理,相关逻辑实现在 bean 的实例化部分,后面会详细介绍。

2、实例化的前置处理

@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
   //如果尚未被解析
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // Make sure bean class is actually resolved at this point.
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}
  • applyBeanPostProcessorsBeforeInstantiation 是对后处理器中所有的 InstantiationAwareBeanPostProcessor 类型的后处理器进行 postProcessBeforeInstantiation 方法的调用。

  • applyBeanPostProcessorsAfterInitialization 是对所有 BeanPostProcessor 的 postProcessAfterInitialization 方法进行调用。

1)、实例化前的后处理器应用

bean 的实例化前调用,也就是将 AbstractBeanDefinition 转换成 BeanWrapper 前的处理。这里是给子类一个修改 BeanDefinition 的机会,当经过这个方法后,bean 可能会成为一个经过处理的代理 bean,可能是通过 cglib 生成的,也可能是其他技术生成的。

//在实例化之前应用 BeanPostProcessors
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
        Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
        if (result != null) {
            return result;
        }
    }
    return null;
}
2)、实例化后的后处理器应用
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值