Spring IoC 原理剖析

1. IoC 容器

Spring IoC 负责创建对象、管理对象(通过依赖注入)、装配对象、配置对象,并且管理这些对象的整个生命周期。

1.1. IoC 的容器接口设计图

image

1.1.1. BeanFactory

其中,BeanFactory 是 Spring IoC 容器的最顶层的接口,定义了基本的 IoC 容器的规范。它只提供了 IOC 容器最基本的功能,所以我们称它为简单容器。它主要是负责配置、生产和管理 bean,其内部定义了对单个 bean 的获取,对 bean 的作用域判断,获取 bean 类型,获取bean别名等功能

1.1.2. ApplicationContext

ApplicationContext 扩展了 BeanFactory,所以,ApplicationContext 包含 BeanFactory 的所有功能,同时它又继承了 MessageSource、ListableBeanFactory、ResourceLoader、ApplicationEventPublisher 等接口,这样 ApplicationContext 为 BeanFactory 赋予了更高级的 IOC 容器特性,我们称它为高级容器。

在实际应用中,一般不使用 BeanFactory,通常建议优先使用 ApplicationContext。

上面两个重要的类都是接口,IOC 容器的实现类是 BeanFactory 子类 DefaultListableBeanFactory 类,它实现了包含基本 Spirng IoC 容器所具有的重要功能。

平时我们说 BeanFactory 提供了 IOC 容器最基本的功能和规范,但真正可以作为一个可以独立使用的 IOC 容器,还得是 DefaultListableBeanFactory,因为它真正实现了 BeanFactory 接口中的方法。所以 DefaultListableBeanFactory 是整个 Spring IOC 的始祖,在 Spring 中实际上把它当成默认的 IoC 容器来使用。

1.2. BeanFactory 容器设计原理

以 DefaultListableBeanFactory 的实现为例,来说明简单 IoC 容器的设计原理:

image

其中,BeanFactory实现是 IoC 容器的基本形式,各种 ApplicationContext 的实现是 IoC 容器的高级表现形式

1.2.1. 编程式使用IOC容器

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new ClassPathResource("UserBean.xml"));

UserService userService = factory.getBean("userService", UserService.class);

1.3. ApplicationContext

ApplicationContext 是一个高级形态意义的 IoC 容器:

  • 支持不同的信息源:继承接口Messagesource

  • 访问资源:继承接口ResourceLoader

  • 支持应用事件

  • 在ApplicationContext中提供附加功能

1.3.1. 设计原理

以 FileSystemXmlApplicationContext 为例,来说明 ApplicationContext 的设计原理:

image

其中,ApplicationContext 的主要功能在基类 AbstractRefreshableApplicationContext 中已经实现了。

上面的类图可以看出,ConfigurableApplicationContext 的父接口 ApplicationContext:

  • 继承了 ListableBeanFactory 用于提供访问应用组件的方法

  • 继承了 ResourceLoader 用于提供加载资源文件的方法

  • 继承了 ApplicationEventPublisher 用于提供发布事件与注册监听器的方法

  • 继承了 MessageSource 提供国际化的支持

2. IoC 容器的初始化过程

2.1. 核心流程

IoC 容器初始化的核心流程,主要就体现在 refresh() 方法中,其实现如下:

// org/springframework/context/support/AbstractApplicationContext.java
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
...
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        this.startupShutdownLock.lock();
        try {
            this.startupShutdownThread = Thread.currentThread();

            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

            // 1.Prepare this context for refreshing.
            prepareRefresh(); // 1.准备刷新上下文环境

            // 2.Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 2.获取初始化Bean工厂

            // 3.Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory); // 3.对bean工厂进行填充属性

            try {
                // 4.Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory); // 4.Spring 开放接口 留给子类去实现该接口

                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                // 5.Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory); // 5.调用 bean 工厂的后置处理器

                //6.Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory); // 6.注册bean后置处理器
                beanPostProcess.end();

                // 7.Initialize message source for this context.
                initMessageSource(); // 7.初始化国际化资源处理器

                // 8.Initialize event multicaster for this context.
                initApplicationEventMulticaster(); // 8.初始化事件多播器

                // 9.Initialize other special beans in specific context subclasses.
                onRefresh(); // 9.这个方法也是留个子类实现,其中springboot也是从这个方法进行tomcat的启动

                // 10.Check for listener beans and register them.
                registerListeners(); // 10.把事件监听器注册到多播器上

                // 11.Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory); // 11.实例化所有的非懒加载的单实例bean

                // 12.Last step: publish corresponding event.
                finishRefresh(); // 12.刷新容器,发布刷新事件(Spring cloud eureka也是从这里启动的)
            }

            catch (RuntimeException | Error ex ) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                contextRefresh.end();
            }
        }
        finally {
            this.startupShutdownThread = null;
            this.startupShutdownLock.unlock();
        }
    }
...
}

2.2. 代码实现

2.2.1. 创建 Bean 容器前的准备工作

prepareRefresh():准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符。

protected void prepareRefresh() {
    // 记录启动时间
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);

    if (logger.isDebugEnabled()) {
        if (logger.isTraceEnabled()) {
            logger.trace("Refreshing " + this);
        }
        else {
            logger.debug("Refreshing " + getDisplayName());
        }
    }

    // Initialize any placeholder property sources in the context environment.
    initPropertySources(); // 初始化上下文环境

    // 校验 XML 配置文件:校验我们容器启动必须依赖的环境变量的值
    getEnvironment().validateRequiredProperties();
    // 创建一个早期事件监听器对象
    // Store pre-refresh ApplicationListeners...
    if (this.earlyApplicationListeners == null) {
        this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    }
    else {
        // Reset local application listeners to pre-refresh state.
        this.applicationListeners.clear();
        this.applicationListeners.addAll(this.earlyApplicationListeners);
    }
    // 创建一个容器用于保存早期待发布的事件集合
    // Allow for the collection of early ApplicationEvents,
    // to be published once the multicaster is available...
    this.earlyApplicationEvents = new LinkedHashSet<>();
}

2.2.2. 创建 Bean 容器,加载并注册 Bean

obtainFreshBeanFactory():这个方法是全文最重要的部分之一,这里将会初始化 BeanFactory、加载 Bean、注册 Bean 等等。

BeanDefinition 就是我们所说的 Spring 的 Bean,我们定义的各个 Bean 其实会转换成一个个 BeanDefinition 存在于 Spring 的 BeanFactory 中。Bean 在代码层面上可以简单认为是 BeanDefinition 的实例。
BeanDefinition 中保存了我们的 Bean 信息,比如这个 Bean 指向的是哪个类、是否是单例的、是否懒加载、这个 Bean 依赖了哪些 Bean 等等。

这一步会把配置文件就会解析成一个个的 Bean 定义,注册到 BeanFactory 中

// AbstractApplicationContext.java
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory(); // 返回刚刚创建的 BeanFactory
}

它会调用子类 AbstractRefreshableApplicationContext 的 refreshBeanFactory() 方法实现来刷新内部的 BeanFactory。

2.2.2.1. 刷新 BeanFactory

其中,载入 Bean 定义信息的具体过程如下:

public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
    ...
    @Override
    protected final void refreshBeanFactory() throws BeansException {
        if (hasBeanFactory()) { // 如果 ApplicationContext 中已经加载过 BeanFactory 了,它会先销毁所有 Bean,并关闭 BeanFactory
            destroyBeans();
            closeBeanFactory();
        }
        try {
            DefaultListableBeanFactory beanFactory = createBeanFactory(); // 初始化一个 DefaultListableBeanFactory
            beanFactory.setSerializationId(getId()); // 用于 BeanFactory 的序列化
            customizeBeanFactory(beanFactory); // 设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
            loadBeanDefinitions(beanFactory); // 加载 Bean 到 BeanFactory 中
            this.beanFactory = beanFactory;
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }
    ...
}

ApplicationContext 虽然继承自 BeanFactory,但是它不应该被理解为 BeanFactory 的实现类,而是其内部持有一个实例化的 BeanFactory,即 DefaultListableBeanFactory ,后续所有的 BeanFactory 相关的操作其实是委托给这个实例来处理的。

上述代码中,最开始会创建一个 DefaultListableBeanFactory,并保存在 ApplicationContext 中,这一步的主要的方法是:loadBeanDefinitions()。

2.2.2.2. 加载 Bean

loadBeanDefinitions():这个方法将根据配置,加载各个 Bean,然后放到 BeanFactory 中

其中,loadBeanDefinitions() 的实现如下:

public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {
    ...
    @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // Create a new XmlBeanDefinitionReader for the given BeanFactory.
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        // Configure the bean definition reader with this context's
        // resource loading environment.
        beanDefinitionReader.setEnvironment(getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

        // Allow a subclass to provide custom initialization of the reader,
        // then proceed with actually loading the bean definitions.
        initBeanDefinitionReader(beanDefinitionReader);
        loadBeanDefinitions(beanDefinitionReader);
    }
    ...
}

到这里已经初始化了 Bean 容器, 配置也相应的转换为了一个个 BeanDefinition,然后注册了各个 BeanDefinition 到注册中心,并且发送了注册事件。

2.2.3. 对 Bean 工厂进行填充属性

prepareBeanFactory(beanFactory):在使用 ApplicationContext 时需要做一些准备工作。

这些准备工作是在这一步处理的,包括:为容器配置 ClassLoader、PropertyEditor 和 BeanPost-Processor 等,从而为容器的启动做好必要的准备。

其代码实现如下:

// org/springframework/context/support/AbstractApplicationContext.java
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // Tell the internal bean factory to use the context's class loader etc.
    // 设置bean工厂的类加载器为当前application应用上下文的加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    // 为bean工厂设置SPEL表达式解析器对象StandardBeanExpressionResolver
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    // 为bean工厂设置了一个propertyEditor属性资源编辑器对象(用于后面的给bean对象赋值使用)
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // 注册ApplicationContextAwareProcessor后置处理器用来处理ApplicationContextAware接口的回调方法
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);

    // BeanFactory interface not registered as resolvable type in a plain factory.
    // MessageSource registered (and found for autowiring) as a bean.
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    // 注册一个事件监听器探测器后置处理器接口
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // Detect a LoadTimeWeaver and prepare for weaving, if found.
    if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        // Set a temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // Register default environment beans.
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
    if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
        beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
    }
}

2.2.4. postProcessBeanFactory(beanFactory)

postProcessBeanFactory(beanFactory):Spring 开放接口留给子类去实现该接口,主要用来改变 BeanFactory。

为了能够修改 bean definitions,或者对 BeanFactory 做一些其他配置,就可以通过继承 ClassPathXmlApplicationContext 类,并重写 postProcessBeanFactory 方法即可。

例如,为 BeanFactory 添加一些自己的 BeanPostProcessor(Bean的后置处理器)。

2.2.5. 调用 bean 工厂的后置处理器

invokeBeanFactoryPostProcessors(beanFactory):调用 bean 工厂的后置处理器,拿到当前应用上下文 beanFactoryPostProcessors 变量中的值,实例化并调用所有已注册的 BeanFactoryPostProcessor。

2.2.6. 注册 bean 后置处理器

registerBeanPostProcessors(beanFactory):注册 bean 后置处理器:

2.2.7. 初始化国际化资源处理器

initMessageSource():初始化国际化资源处理器。

2.2.8. 初始化事件多播器

initApplicationEventMulticaster():初始化事件多播器。

2.2.9. onRefresh()

onRefresh():这个方法很重要,同样也是留个子类实现,其中 Spring Boot 就是从这个方法进行 tomcat 的启动。

2.2.10. registerListeners()

registerListeners():把事件监听器注册到事件多播器上。

其代码实现如下:

// org/springframework/context/support/AbstractApplicationContext.java
protected void registerListeners() {
    // 把容器中的监听器注册到事件多播器上
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let post-processors apply to them!
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        // 把监听器的名称注册到的事件多播器上
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }
    // 获取早期事件
    // Publish early application events now that we finally have a multicaster...
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            // 通过多播器播发早期事件
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

2.2.11. 初始化所有的 singleton Bean

finishBeanFactoryInitialization(beanFactory)实例化所有的非懒加载的单实例 bean

到目前为止,应该说 BeanFactory 已经创建完成,并且所有的实现了 BeanFactoryPostProcessor 接口的 Bean 都已经初始化并且其中的 postProcessBeanFactory(factory) 方法已经得到回调执行了。而且 Spring 已经“手动”注册了一些特殊的 Bean,如 environment、systemProperties 等。

剩下的就是初始化 singleton bean 了,我们知道它们是单例的,如果没有设置懒加载,那么,Spring 会在接下来初始化所有的 singleton beans。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // Initialize conversion service for this context.
    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));
    }

    // Register a default embedded value resolver if no BeanFactoryPostProcessor
    // (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
    // at this point, primarily for resolution in annotation attribute values.
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    // Stop using the temporary ClassLoader for type matching.
    beanFactory.setTempClassLoader(null);

    // Allow for caching all bean definition metadata, not expecting further changes.
    beanFactory.freezeConfiguration();

    // Instantiate all remaining (non-lazy-init) singletons.
    beanFactory.preInstantiateSingletons(); // 开始初始化
}

2.2.11.1. preInstantiateSingletons

其中,preInstantiateSingletons() 的实现如下:

// org/springframework/beans/factory/support/DefaultListableBeanFactory.java
public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
        logger.trace("Pre-instantiating singletons in " + this);
    }

    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isEagerInit()) {
                    getBean(beanName);
                }
            }
            else {
                getBean(beanName); // 对于普通的 Bean,只要调用 getBean(beanName) 这个方法就可以进行初始化了
            }
        }
    }

    // Trigger post-initialization callback for all applicable beans...
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton smartSingleton) {
            StartupStep smartInitialize = getApplicationStartup().start("spring.beans.smart-initialize")
                    .tag("beanName", beanName);
            smartSingleton.afterSingletonsInstantiated();
            smartInitialize.end();
        }
    }
}

2.2.11.2. getBean

其中,getBean 的实现如下:

// org/springframework/beans/factory/support/AbstractBeanFactory.java
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}

protected <T> T doGetBean(
    String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
    throws BeansException {
    // ...
    return createBean(beanName, mbd, args);
    // ...
}

2.2.11.3. 创建 Bean 实例的过程

doCreateBean():创建 Bean 实例,它会调用 doCreateBean() 完成实例的创建、属性注入、处理循环依赖等流程。

// org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {
    // ...
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    // ...
}

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {
    // ...
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);  // 创建 Bean 实例
    }
    // ...
    // 依赖注入:属性注入
    populateBean(beanName, mbd, instanceWrapper);
    // 调用bean factory的回调,执行bean初始化的后处理流程
    exposedObject = initializeBean(beanName, exposedObject, mbd);
    // ...
    // 处理循环依赖
    if (earlySingletonExposure) {
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            }
            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                if (!actualDependentBeans.isEmpty()) {
                    // ...
                }
            }
        }
    }
}
2.2.11.3.1. 创建 Bean 实例
// org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // Make sure bean class is actually resolved at this point.
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    // ...
    if (resolved) {
        if (autowireNecessary) {
            return autowireConstructor(beanName, mbd, null, null); // 构造函数依赖注入
        }
        else {
            return instantiateBean(beanName, mbd); // 无参构造函数依赖注入
        }
    }

    // Candidate constructors for autowiring?
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // Preferred constructors for default construction?
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    // No special handling: simply use no-arg constructor.
    return instantiateBean(beanName, mbd); // 无参构造函数依赖注入
}

这里,我们以无参构造函数的依赖注入为例来介绍其注入过程,其代码实现下:

// org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
    try {
        Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this); // 实例化
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);
        initBeanWrapper(bw);
        return bw;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), ex);
    }
}

instantiate() 方法的实现如下:

// org/springframework/beans/factory/support/SimpleInstantiationStrategy.java
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    if (!bd.hasMethodOverrides()) {
        // ...
        // 利用构造方法进行实例化
        return BeanUtils.instantiateClass(constructorToUse);
    }
    else {
        // ...
        // 存在方法覆写,利用 CGLIB 来完成实例化,需要依赖于 CGLIB 生成子类
        return instantiateWithMethodInjection(bd, beanName, owner);
    }
}
2.2.11.3.2. Bean 属性注入

populateBean(beanName, mbd, instanceWrapper):负责进行属性设值,处理依赖。

其代码实现如下:

// org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    if (bw == null) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        }
        else {
            // Skip property population phase for null instance.
            return;
        }
    }

    if (bw.getWrappedClass().isRecord()) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Cannot apply property values to a record");
        }
        else {
            // Skip property population phase for records since they are immutable.
            return;
        }
    }

    // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    // state of the bean before properties are set. This can be used, for example,
    // to support styles of field injection.
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                return;
            }
        }
    }

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

    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        // Add property values based on autowire by name if applicable.
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        // Add property values based on autowire by type if applicable.
        if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }
    if (hasInstantiationAwareBeanPostProcessors()) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
                return;
            }
            pvs = pvsToUse;
        }
    }

    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
    if (needsDepCheck) {
        PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        checkDependencies(beanName, mbd, filteredPds, pvs);
    }

    if (pvs != null) {
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}
2.2.11.3.3. 回调处理

initializeBean(beanName, exposedObject, mbd):处理各种回调。

属性注入完成后,这一步其实就是处理各种回调了,这块代码比较简单。

其代码实现如下:

// org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    invokeAwareMethods(beanName, bean);

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

参考:

posted @ 2024-01-16 18:12  LARRY1024  阅读(261)  评论(0编辑  收藏  举报