我需要根据 Spring 应用程序在运行时检测到的环境,有条件地创建服务的三种可能实现之一。如果服务 A 可用,那么我想创建一个使用服务 A 作为依赖项的具体实现类。如果服务 A 不可用,那么我想创建一个使用服务 B 作为依赖项的实现。等等。
依赖于实现的类将 Autowiring 接口(interface),而不关心为特定环境选择的底层服务是什么。
我的第一个尝试是实现多个 @Bean 方法,这些方法要么返回 bean,要么返回 null,具体取决于 Service 是否可用,然后有一个单独的 @Configuration 类,其中 @Autowire(required=false) 两种可能的服务,根据哪个@Autowired 字段不为空,有条件地创建实现。
这里的问题是,当 required=false 时,Spring 似乎并不关心它是否等待构建候选者;也就是说,尝试选择实现的类可能在一个或两个 required=false Bean 被构建之前构建,从而确保一个或两个可能始终为空,无论它是否可以正确初始化。
感觉就像我在这一点上违背了 Cereal ,所以我正在寻找关于做这种事情的“正确”方式的建议,根据可用性,一整套 bean 可能会被换掉一些外部服务或环境。
配置文件看起来不是正确的答案,因为直到我的服务 bean 尝试初始化我想要选择的实现之后,我才会知道;在我创建上下文时,我当然不会知道。
@Order 也没有实现目标。 @Conditional 和测试 bean 的存在也没有(因为它可能还没有被构造)。 FactoryBean 也存在同样的问题 - 检查是否存在在要求 FactoryBean 创建实例时可能尚未构建的 bean 是没有用的。
我真正需要做的是根据其他 bean 的可用性创建一个 Bean,但只有在这些 bean 至少有机会尝试初始化之后。
最佳答案
Spring Profiles 是您的 friend 。您可以通过环境变量、命令行参数和其他方法设置当前配置文件。您可以注释 Spring 管理的组件,以便为某个配置文件创建它。
Spring Profiles from the Spring Documentation
关于基于服务可用性的 Spring Autowiring ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42865940/