如何在Spring中根据配置文件调用不同的Bean实现

4

我需要添加多个接口实现,其中一个应该根据配置文件进行选择。

例如:

interface Test{
    public void test();
}

@Service
@Profile("local")
class Service1 implements Test{
    public void test(){

    }
}

@Service
class Service2 implements Test{
    public void test(){

    }
}


@SpringBootApplication
public class Application {

    private final Test test;

    public Application(final Test test) {
        this.test = test;
    }

    @PostConstruct
    public void setup() {
        test.test();
    }
}

我的意图是在使用-Dspring.profiles.active=local时调用Service1,否则调用service2,但我收到了一个异常错误,提示缺少Test的bean。


1
当询问异常时,始终发布完整的错误和堆栈跟踪。 - JB Nizet
我认为你应该创建两个配置文件,一个用于Service1,另一个用于Service2。 如果你使用-Dspring.profiles.active=local来运行它,那么这两个bean都将被创建。 - Mehdi Benmesssaoud
2个回答

5

Service2 添加默认配置文件:

@Service
@Profile("default")
class Service2 implements Test{
    public void test(){

    }
}

如果没有识别到其他配置文件,bean 将仅被添加到上下文中。如果传入不同的配置文件,例如 -Dspring.profiles.active="demo",则会忽略此配置文件。

如果您想要除了 local 以外的所有配置文件使用 NOT 运算符

@Profile("!local")

如果给定的配置文件前缀带有 NOT 运算符(!),则如果该配置文件未激活,将注册已注释组件。

我需要一个用于调试的虚拟实现,所以我在它上面使用了 @Primary @Component @Profile("dev")(并在本地运行时将配置文件设置为 dev)。 - Emiliano Ruiz

0

您可以在Service2中添加@ConditionalOnMissingBean,这意味着只有在不存在其他实现的情况下才会使用它,这将使Service2成为除本地配置文件以外的任何其他配置文件中的默认实现。

@Service
@ConditionalOnMissingBean
class Service2 implements Test {
    public void test() {}
}

然而,有一个警告。ConditionalOnMissingBean Javadoc说:“条件只能匹配应用程序上下文到目前为止已处理的bean定义,因此强烈建议仅在自动配置类上使用此条件。” - Petr Gladkikh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接