java - 按需实例化 Spring beans,而不是在启动时实例化

标签 java spring spring-boot dependency-injection

这里是 Spring Boot 2.x。我目前在 @Configuration 类中定义了一堆 bean,如下所示:

@Configuration
public class SomeConfig {

    @Bean
    public Fizz fizz() { ... }

    @Bean
    public Buzz buzz() { ... }

}

通常,Spring 将启动此类并在启动时实例化这些 bean。然而,就我而言,我希望 Spring 在启动时跳过加载此类(并实例化它的 beans),而是以编程方式/按需执行,如下所示:

public void processRequest(SomeRequest request) {

    Fizz fizz = SpringAdhocLoader.load(SomeConfig.class, Fizz.class);
    Buzz buzz = SpringAdhocLoader.load(SomeConfig.class, Buzz.class);

    // use these two beans in this method somehow

}

我需要这样做有一个非常具体的原因,这超出了这个问题的范围。因此,我真的非常感谢您回答“是的,您可以做到这一点,这就是如何...”或“不,这是无法完成的” Spring ,这就是为什么......”,而不是回答/评论问我为什么我想这样做。相信我,我需要!

最终,我正在寻找一种方法来告诉 Spring 不要实例化我的 SomeConfig 类中的所有 bean,直到我的代码的另一部分特别希望创建它们。这可能吗?如果可能的话,如何实现?


更新

如果 Fizz 看起来像这样怎么办:

@Component
public class Foobar {
    ...
}

public class Fizz {

    @Autowired
    private Foobar foobar;

    ...
}

SomeConfig 上的 @Lazy 注释是否仍然会在实例化 Fizz 时停止,即使它是 Autowiring /注入(inject)的具有 @Component 依赖项?

最佳答案

根据您的具体要求,有多种方法可以实现此目的:

  • 如果每个人都应该使用相同的对象实例,则使用@Lazy,自动调用销毁回调,并在首次请求 bean 时创建对象。

  • 使用生命周期较短的@Scope,例如“ session ”或“请求”,如果该范围内的每个人都应该使用相同的对象实例,则会自动调用销毁回调,并且第一次请求时创建对象。

  • 如果每个人都应该获得一个新的对象实例,并且您愿意手动调用任何销毁回调,请使用@Scope("prototype")

在所有情况下,注入(inject)“裸”bean 都会请求创建该 bean。您可以通过注入(inject) Provider 来避免这种情况:

class Foo {
    @Inject Bar bar;  // requests the creation of bar
}

class Foo {
    @Inject Provider<Bar> barProvider; // does not cause the creation of bar

    void something() {
        Bar bar = barProvider.get(); // requests the creation of bar 
    }
}

关于java - 按需实例化 Spring beans,而不是在启动时实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58328663/

相关文章:

java - 从 Android Java 调用 native 函数 - JNI 的替代方案

java - 如何从参数请求的值迭代

java - 在 Elasticsearch 中忽略 JsonIgnore

spring-boot - 如何在 Spring Boot 应用程序中 Autowiring 默认的 XmlMapper

java - 为什么将 SparkSql 与 Hive 一起使用时找不到此表错误?

java - wait(some time) 是否必须始终采用同步方法?

java - 是否可以在java中实例化接口(interface)?

java - 无法实例化 [org.thymeleaf.templateresolver.ServletContextTemplateResolver] : No default constructor found

java - 如何在 Weblogic 12c (12.1.3) 上部署 Spring Boot 应用程序?

elasticsearch - 使用Spring Boot + Spring Data Elasticsearch的嵌套文档和父/子设置