@Profile solution
You definitely need to try Spring 3.1 @Profile :
@Autowire private MyService communicator; //... @Service @Profile("prd") class MyServiceImpl //... @Service @Profile("qa") class MyServiceStub //...
Now, depending on which profile is enabled, either DefaultMyService will be initialized, or MyServiceStub .
You can choose between profiles in various ways:
Spring AOP (explicit for each method)
In this example, an aspect wraps around each individual MyService method separately and returns a fading value:
@Aspect @Service public class StubAspect { @Around("execution(public * com.blogspot.nurkiewicz.MyService.foo(..))") public Object aroundFoo(ProceedingJoinPoint pjp) throws Throwable { if (stubMode()) { return
The code is pretty simple, unfortunately, the return values ββare hidden inside the aspect, and a separate @Around is required for each target method. Finally, there is no room for MyServiceStub .
Spring AOP (automatically around all methods)
@Aspect @Service public class StubAspect { private MyServiceStub stub =
This approach is more implicit because it automatically wraps each target method, including new methods added in the future. The idea is simple: if stubMode() turned off, run the standard method ( pjp.proceed() ). If it is enabled, the same method with exactly the same parameters, but on a different object (in this case, a stub).
This solution is much better because it involves less manual work (at the cost of using raw reflection).
Note that if both implementations of MyService Spring beans (even if one of them is annotated using @Primary ), you may run into confusion. But that should be a good start.
See also: