我的Google Guice方法拦截器没有执行,但为什么?

时间:2014-05-03 16:00:07

标签: java dependency-injection guice

所以我正在测试一个简单的Google Guice拦截器 -

我的注释 -

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD)
public @interface AppOpsOperation {

}

我的拦截器

public class AppOpsOperationDecorator implements MethodInterceptor {

    private ServiceCallStack callStack = null ;

    @Inject
    public void setServiceCallStack(ServiceCallStack stack ){
        callStack = stack ;
    }

    @Override
    public Object invoke(MethodInvocation arg0) throws Throwable {

        // Retrieve the call stack 
        // exclude service population if caller service is the same service 
        // else push the current service onto top of stack 

        System.out.println("Intercepting method  -- ::  " + arg0.getMethod().getName());
        System.out.println("On object             - ::  " + arg0.getThis().getClass().getName());
        System.out.println("On accessible object  - ::  " + arg0.getStaticPart().getClass().getName());
        return invocation.proceed();
    }

}

现在我的服务界面和方法

public interface MockCalledService extends AppOpsService {

@AppOpsOperation
public String methodOneCalled(String some);

@AppOpsOperation
public String methodTwoCalled(String some);
}

public class MockCalledServiceImpl extends BaseAppOpsService implements MockCalledService {

@Override
@AppOpsOperation
public String methodOneCalled(String some) {
    System.out.println("MockCalledServiceImpl.methodOneCalled()");
    return this.getClass().getCanonicalName() + "methodOneCalled";
}

@Override
public String methodTwoCalled(String some) {
    System.out.println("MockCalledServiceImpl.methodTwoCalled()");
    return this.getClass().getCanonicalName() + "methodTwoCalled";
}

}

我的Guice测试模块

public class MockTestGuiceModule extends AbstractModule {

@Override
protected void configure() {

    bind(ServiceCallStack.class).toInstance(new ServiceCallStack());

    AppOpsOperationDecorator decorator = new AppOpsOperationDecorator() ;

    requestInjection(decorator);

    bindInterceptor(Matchers.any(), Matchers.annotatedWith(AppOpsOperation.class), 
             decorator);

    bind(MockCalledService.class).toInstance(new MockCalledServiceImpl());
}

}

当我在下面运行测试时,此拦截器不会执行 -

public class AppOpsOperationDecoratorTest {

private Injector injector = null ;

@Before
public void init(){
    injector =  Guice.createInjector(new MockTestGuiceModule());
}

@Test
public void testDecoratorInvocation() {

    MockCalledService called = injector.getInstance(MockCalledService.class);

    called.methodOneCalled("Test String");

}

}

你能否强调一下我做错了什么?

1 个答案:

答案 0 :(得分:2)

我在找到真正的原因后回答。它非常简单,非常棘手。

方法拦截仅在将接口与类绑定而不是此实现的实例时才有效。

所以代替'bind(MockCalledService.class).toInstance(new MockCalledServiceImpl());'

我们应该写'bind(MockCalledService.class).toInstance(MockCalledServiceImpl.class);'

似乎没有代理实例:(