Spring 容器内部调用的魔法之旅

你好!本文将为大家揭秘 Spring 容器内部的魔术之旅。我们将一步步地探索 Spring 容器内部的调用流程,特别是 @Configuration 注解的 Full 模式和 Lite 模式。

Full 模式和 Lite 模式

在 Spring Framework 中,@Configuration 注解可以有两种模式:Full 模式和 Lite 模式。Full 模式下,所有配置类方法都将被注册为 BeanFactoryPostProcessor,而 Lite 模式则只注册 ConfigurationClassPostProcessor。

@Configuration 的底层实现

让我们先看一下 @Configuration 的底层实现:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Configuration {
    // ...
}

invokeBeanDefinitionMethod 方法

当 Spring 容器内部调用一个配置类的方法时,会触发 invokeBeanDefinitionMethod 方法:

protected void invokeBeanDefinitionMethod(MergedBeanDefinitionPostProcessor processor, String beanName, Object... args) {
    if (processor != null) {
        // ...
    } else {
        resolveBeanReference(beanName, args);
    }
}

isCurrentlyInvokedFactoryMethod 方法

在 invokeBeanDefinitionMethod 方法中,会检查当前是否正在被 FactoryMethod 调用:

private boolean isCurrentlyInvokedFactoryMethod() {
    // 如果是在 FactoryMethod 中调用的,则返回 false
    return factoryMethodCurrentlyInvoked;
}

invokeSuper 方法

如果是直接调用 dog() 方法,则 willInvokeSuper 方法会返回 true,触发 invokeSuper 方法:

protected void invokeSuper(MergedBeanDefinitionPostProcessor processor, String beanName, Object... args) {
    // 真正的触发 Bean 的创建流程
}

resolveBeanReference 方法

如果是在 user() 方法中调用的 dog() 方法,则 willInvokeSuper 方法会返回 false,触发 resolveBeanReference 方法:

protected void resolveBeanReference(String beanName, Object... args) {
    // 先去 Spring 容器中查找相应的 Bean,如果不存在则会触发 Bean 的创建流程
}

Full 模式下的优化

在 Full 模式下,由于所有配置类方法都会被注册为 BeanFactoryPostProcessor,因此当你调用一个 @Bean 注解标记的方法时,并不会导致 Bean 的重复创建。

例子

@Configuration
public class Config {
    @Bean
    public Dog dog() {
        return new Dog();
    }

    @Bean
    public User user() {
        return new User(dog());
    }
}

在上面的例子中,dog() 方法将被注册为 BeanFactoryPostProcessor,而 user() 方法则会使用 resolveBeanReference 方法来查找 dog() Bean 的引用。

总结

本文揭秘了 Spring 容器内部的魔术之旅,特别是 @Configuration 注解的 Full 模式和 Lite 模式。我们学习了 invokeBeanDefinitionMethod 方法、isCurrentlyInvokedFactoryMethod 方法、invokeSuper 方法和 resolveBeanReference 方法的作用,并结合例子来理解这些方法的实现细节。

应用案例

在实际开发中,了解 Spring 容器内部的调用的流程非常重要。例如,在一个 Spring Boot 应用中,如果你需要动态加载 Bean 的引用,你可以使用 resolveBeanReference 方法来实现。


来源: 互联网
本文观点不代表源码解析立场,不承担法律责任,文章及观点也不构成任何投资意见。

赞 ()

相关推荐

发表回复

评论列表

点击查看更多

    联系我们

    在线咨询: QQ交谈

    微信:13450247865

    邮件:451255340#qq.com

    工作时间:周一至周五,9:30-18:30,节假日休息

    微信