Not loading a Spring bean when a certain profile is set

空扰寡人 提交于 2019-12-06 20:13:04

问题


Background: So, I've got several beans that interface external systems. For development, it's convenient to mock the external systems and replace the interfacing beans with some implementations that produce more or less static responses. So what I've been doing is to create an interface, the real implementation and a stub implementation like this:

public interface ExternalService {
// ...
}

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

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

...and this works great: if the stub profile is not present, the stub-bean does not get loaded at all. If it is present, it nicely supersedes the real implementation because of the @Primary annotation.

Problem: Now, however, I've run for the first time in a situation where I've actually got two real implementations of the same interface. One of them is defined as primary, but the other may also be used by loading it from the application context.

I'd still like to create a stub service to replace them both, but this time my old way of defining the stub as @Primary doesn't work, because there's already one primary implementation. Basically what I'd need is a way of not loading the primary bean when the stub profile is set, but I'm at loss on how exactly to do that. Web searches or other Stack Overflow questions don't seem to be helping.


回答1:


Turns out the answer was surprisingly simple: you add a not-operator (!) in front of the profile name:

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

This way the bean is only loaded when the stub-profile is not active. The support for this feature was added in Spring 3.2 M1.

There's one caveat, though: if you write @Profile({"!stub", "foo"}), the comma is treated as "or", not "and". So this example bean would be activated either if stub was not active or if foo was active.

Edit/Add: Spring 5.1 added a support for a new expression language for profiles: !stub & foo is activated when stub is not active and foo is active. Great success! You can even mix and match ands and ors provided that you use parenthesis: production & (us-east | eu-central).



来源:https://stackoverflow.com/questions/25076557/not-loading-a-spring-bean-when-a-certain-profile-is-set

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!