简体   繁体   English

Spring外部库bean初始化顺序

[英]Spring external library beans initialization order

I've encountered a problem in my application and somehow i need to force one bean A to be initialized before another bean B. These beans are provided by external dependencies (different dependencies) so I cannot simply do it with @DependsOn annotation.我在我的应用程序中遇到了一个问题,不知何故我需要强制一个 bean A 在另一个 bean B 之前初始化。这些 bean 是由外部依赖项(不同的依赖项)提供的,所以我不能简单地使用@DependsOn注释来完成。
Is there any solution available?有没有可用的解决方案?

I set up a simple (modular, maven) project and did experience no issues using @DependsOn annotation on an "external component".我设置了一个简单的(模块化的,maven)项目,并且在“外部组件”上使用@DependsOn注释没有遇到任何问题。 Only few things to accomplish:只需要完成几件事:

  1. Ensure A is in the (runtime) classpath of B .确保AB的(运行时)类路径中。
  2. Ensure B 's application context @ComponentScan s (also) A .确保B的应用程序上下文@ComponentScan s(也) A
  3. Find out/guess the "logical bean name" of A and use that value in your @DependsOn annotation.找出/猜测的“逻辑bean的名字” A ,在你使用该值@DependsOn注解。 ..then @DependsOn works as expected (also on "external dependencies"). ..then @DependsOn按预期工作(也适用于“外部依赖项”)。

The sample uses , but (I am sure) the configuration details are applicable to a "boot-less" environment/context.该示例使用 ,但(我确信)配置详细信息适用于“无引导”环境/上下文。


And considering the javadoc of DependsOn:并考虑 DependsOn 的 javadoc:

Used infrequently in cases where a bean does not explicitly depend on another through properties or constructor arguments, but rather depends on the side effects of another bean's initialization.在 bean 不通过属性或构造函数参数显式依赖另一个 bean,而是依赖另一个 bean 初始化的副作用的情况下,很少使用。

@Autowired would give you the same effect (with similar effort), but with type safety/without "name guessing" - I added it to the sample . @Autowired会给你同样的效果(用类似的努力),但类型安全/没有“名字猜测” - 我将它添加到示例中


REWORK : Regarding this from a third project (baz), you have again several options to force A initialization before B .返工:关于这个来自第三个项目 (baz),您再次有几个选项可以在B之前强制A初始化。

  1. If A and B initialization is trivial (eg default constructor), you can proceed in your configuration/application like this:如果AB初始化是微不足道的(例如默认构造函数),您可以像这样继续配置/应用程序:

     import ...A; import ...B; ... @Configuration// @SpringBootApplication ..or idempotent public class MyConfig { ... @Bean("a") public A a() { return new A(); } @Bean @DependsOn("a") public B b() { return new B(); } ... }
  2. If initialization (of A and B) is not trivial, but you can refer to existing (external) Configurations, then this works (redefining autowired beans, adding dependsOn annotation):如果初始化(A 和 B)不是微不足道的,但您可以参考现有的(外部)配置,那么这有效(重新定义自动装配的 bean,添加 dependsOn 注释):

     @Configuration @Import(value = {BConfig.class, AConfig.class}) class MyConfig { @Bean("a") public A a(@Autowired A a) { return a; } @Bean @DependsOn("a") public B b(@Autowired B b) { return b; } }
  3. You rely on component scan, and redefine the beans (with dependsOn):您依赖于组件扫描,并重新定义 bean(使用dependsOn):

     @Configuration @ComponentScan(basePackageClasses = {B.class, A.class}) class MyConfig { // same as 2. }
  4. ... ...

If the external config (2., 3.) defines the beans with the same "name", then spring.main.allow-bean-definition-overriding property must be set to true (in application.properties or idempotent).如果外部配置 (2., 3.) 定义了具有相同“名称” spring.main.allow-bean-definition-overriding ,则spring.main.allow-bean-definition-overriding属性必须设置为true (在 application.properties 或幂等中)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM