Spring autowire wired service - duplicate bean

Ok We need @Autowire another web service on the fly (preferably by switching the JNDI parameter on the web server), and I don’t understand how to do this. This is how I approached the problems.

Two packages: com.mycomp.service.stub com.mycomp.service.impl

One package contains MyServiceStub.java, while MyService another package contains MyServiceImpl.java, which implements the same

My controller, which requires MyService, has a bean defined as such

@Autowire private MyService communicator; 

My spring -context.xml has the following:

 <context:component-scan base-package="com.mycomp" /> 

At this point, I get a DuplicateBean exception during auto install. Now I can statically determine which bean for autwire in spring -context.xml:

 <bean id="communicator" class="com.mycomp.service.impl.MyServiceImpl" /> 

and everything works fine ... But then, how to "flip" the switch and switch to the Stub method on our QA server? It has nothing to do with this service, so we need to run with stubs turned on. A JNDI property would be best for this. But I just can't figure out how to switch what bean spring is auto-incrementing at runtime.

Any help?

Cheers, Chris

+4
source share
2 answers

@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 //stub foo() result } return pjp.proceed(); } @Around("execution(public * com.blogspot.nurkiewicz.MyService.bar(..))") public Object aroundBar(ProceedingJoinPoint pjp) throws Throwable { if (stubMode()) { return //stub bar() result } return pjp.proceed(); } private boolean stubMode() { //whatever condition you want here return true; } } 

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 = //obtain stub somehow @Around("execution(public * com.blogspot.nurkiewicz.MyService.*(..))") public Object aroundFoo(ProceedingJoinPoint pjp) throws Throwable { if (stubMode()) { MethodSignature signature = (MethodSignature)pjp.getSignature(); Method method = signature.getMethod(); return method.invoke(stub, pjp.getArgs()); } return pjp.proceed(); } private boolean stubMode() { //whatever condition you want here return true; } } 

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:

+5
source

Perhaps you can replace the class with a property and deploy the application using different property files. The production version will contain the name of the real class, while the QA version will contain the name of the stub.

Maybe this http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-extension-factory-postprocessors can help you.

0
source

Source: https://habr.com/ru/post/1393166/


All Articles