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.
@Profile('!dev'
) and then inside you create a bean with@Profile('!prod')
annotation it will work asAND
condition, so in this case: if !dev && !prod . – Cinquefoil