设置某个配置文件时不加载弹簧豆

2022-09-04 07:48:12

背景:所以,我有几个连接外部系统的豆子。对于开发,模拟外部系统并用一些产生或多或少静态响应的实现替换接口bean是很方便的。所以我一直在做的是创建一个接口,真正的实现和一个像这样的存根实现:

public interface ExternalService {
// ...
}

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

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

...这很好用:如果存根配置文件不存在,则存根豆根本不会加载。如果它存在,它很好地取代了真正的实现,因为@Primary注释。

问题:但是,现在,我第一次在实际上有两个相同接口的实际实现的情况下运行。其中一个被定义为主数据库,但另一个也可以通过从应用程序上下文加载它来使用。

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


答案 1

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

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

这样,仅当 -profile 不处于活动状态时才会加载 Bean。对此功能的支持是在Spring 3.2 M1中添加的。stub

但是,有一个警告:如果你写,逗号被视为“or”,而不是“and”。因此,如果此示例 Bean 处于非活动状态或处于活动状态,则将其激活。@Profile({"!stub", "foo"})stubfoo

编辑/添加:Spring 5.1 为配置文件添加了对新表达式语言的支持:在未激活且处于活动状态时激活。大获成功!您甚至可以混合搭配 ands 和 ors,前提是使用括号:。!stub & foostubfooproduction & (us-east | eu-central)


答案 2

推荐