按需实例化 Spring bean,而不是在启动时



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

@Configuration
public class SomeConfig {
@Bean
public Fizz fizz() { ... }
@Bean
public Buzz buzz() { ... }
}

通常,Spring 会启动这个类并在启动时实例化这些 bean。但是,就我而言,我希望 Spring启动时跳过加载此类(并将其实例化为 bean(,而是以编程/按需方式执行此操作,如下所示:

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不要实例化我SomeConfig类中的所有 bean,直到我的代码的另一部分特别希望创建它们。这是否可能,如果可能,如何?


更新

如果Fizz看起来像这样:

@Component
public class Foobar {
...
}
public class Fizz {
@Autowired
private Foobar foobar;
...
}

SomeConfig上的@Lazy注释是否仍然会避免实例化Fizz,即使它自动连线/注入了@Component依赖项?

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

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

  • 使用生存期较短的@Scope,例如"会话"或"请求",如果该范围内的每个人都应使用相同的对象实例,则会自动调用销毁回调,并在首次请求对象时创建对象。

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

在所有情况下,注入"裸"豆将请求创建该豆。您可以通过注入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 
}
}

相关内容

最新更新