当设置了特定的配置文件时,不加载Spring bean。

13

背景:我手头有几个用于接口外部系统的Bean。在开发过程中,为了方便模拟外部系统,我会使用一些实现来替换这些接口Bean,并产生更多或更少静态响应。因此,我一直在创建一个接口,真正的实现和一个存根实现,如下所示:

public interface ExternalService {
// ...
}

@Service
public class ExternalServiceImpl implements ExternalService {
// ...
}

@Service
@Primary
@Profile({"stub"})
public class StubExternalService implements ExternalService {
// ...
}

...这个方法很好:如果存根档案不存在,则不会加载存根bean。如果存在,则由于@Primary注释,它会很好地取代真正的实现。

问题:然而,现在我遇到了一个情况,即我实际上有两个相同接口的真正实现。其中一个被定义为主要实现,但是另一个也可以通过从应用程序上下文中加载来使用。

我仍然想创建一个存根服务来替换它们,但是这次我的旧方法将存根定义为@Primary不起作用,因为已经有一个主要实现了。基本上,我需要一种方式在设置存根配置文件时不加载主bean,但是我不知道具体如何做。网络搜索或其他Stack Overflow问题似乎没有帮助。

1个回答

25
结果证明答案非常简单:在个人资料名称前面添加一个非运算符(!)即可。
@Service
@Primary
@Profile({"!stub"})
public class ExternalServiceImpl implements ExternalService {
// ...
}

这种方式只有在stub配置未激活时才会加载bean。支持此功能是在Spring 3.2 M1中添加的。
然而,有一个警告:如果您编写@Profile({"!stub", "foo"}),逗号将被视为“或”,而不是“和”。因此,此示例bean将被激活,如果stub未激活或者foo已被激活。 编辑/添加:Spring 5.1添加了对新的配置表达式语言的支持:!stub & foo将在stub未激活且foo已激活时激活。非常成功!您甚至可以组合使用逻辑运算符并提供括号:production & (us-east | eu-central)

1
零是正确的,但实际上有一种方法可以获得AND。如果您创建一个特定的配置类并用@Profile('!dev')进行注释,然后在其中创建一个带有@Profile('!prod')注释的bean,它将作为AND条件工作,因此在这种情况下:如果!dev && !prod。 - Daniele

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