背景: 因此,我有几个与外部系统接口的 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 问题似乎没有帮助。

有帮助吗?

解决方案

事实证明答案出奇的简单:您添加一个非运算符(!) 在配置文件名称前面:

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

这样,只有在以下情况下才会加载 bean: stub-配置文件未激活。添加了对此功能的支持 弹簧3.2 M1.

不过,有一点需要注意:如果你写 @Profile({"!stub", "foo"}), ,逗号被视为“或”,而不是“和”。所以这个示例 bean 将被激活,如果 stub 不活跃或者如果 foo 很活跃。

编辑/添加: Spring 5.1 添加了对 新的配置文件表达语言: !stub & foo 被激活时 stub 不活跃并且 foo 活跃。巨大的成功!如果使用括号,您甚至可以混合搭配 and 和 or : production & (us-east | eu-central).

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top