Spring自动装配一个存根服务 - 重复的bean

Chr*_*non 4 java spring autowired

好.我们需要@Autowire一个不同的Web服务(最好是通过在网络服务器上切换JNDI设置),我对如何做到这一点感到茫然.这就是我接近问题的方式..

两个包:com.mycomp.service.stub com.mycomp.service.impl

一个包包含MyServiceStub.java,而实现MyService另一个包包含MyServiceImpl.java,它实现了相同的功能

我的控制器需要MyService,它的bean定义如此

@Autowire
private MyService communicator;
Run Code Online (Sandbox Code Playgroud)

我的spring-context.xml具有以下内容:

<context:component-scan base-package="com.mycomp" />
Run Code Online (Sandbox Code Playgroud)

此时,我在自动装配期间遇到DuplicateBean异常.现在,我可以在spring-context.xml中静态定义要自动装配的bean:

<bean id="communicator" class="com.mycomp.service.impl.MyServiceImpl" />
Run Code Online (Sandbox Code Playgroud)

一切正常......但是,如何"翻转"切换并切换到QA服务器上的Stub方法?它与该服务没有任何关联,因此我们需要在启用存根的情况下运行.JNDI属性对此最好..但我无法理解如何在运行时切换bean spring autowires.

任何帮助?

干杯,克里斯

Tom*_*icz 5

@Profile

你一定要尝试Spring 3.1 @Profile:

@Autowire
private MyService communicator;

//...

@Service
@Profile("prd")
class MyServiceImpl //...

@Service
@Profile("qa")
class MyServiceStub //...
Run Code Online (Sandbox Code Playgroud)

现在,根据启用的配置文件,DefaultMyService将初始化或MyServiceStub.

您可以通过各种方式选择个人资料:

Spring AOP(围绕每个方法显式)

在此示例中,方面分别包装每个MyService方法并返回存根值:

@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;
    }

}
Run Code Online (Sandbox Code Playgroud)

代码非常简单,遗憾的是返回值隐藏在方面内部,并且@Around每个目标方法都需要单独使用.最后,没有地方可以MyServiceStub.

Spring AOP(自动围绕所有方法)

@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;
    }

}
Run Code Online (Sandbox Code Playgroud)

这种方法更隐含,因为它会自动包装每个目标方法,包括将来添加的新方法.这个想法很简单:如果stubMode()关闭,运行标准方法(pjp.proceed()).如果它是 - 运行完全相同的方法与完全相同的参数 - 但在不同的对象(在这种情况下为存根).

这种解决方案要好得多,因为它涉及较少的手工工作(以使用原始反射的代价).

请注意,如果两个MyService实现都是Spring bean(即使有一个注释@Primary),您可能会遇到奇怪的问题.但这应该是一个好的开始.

也可以看看: