【问题标题】:Can't Get Guice Method Interception to Work无法让 Guice 方法拦截工作
【发布时间】:2012-02-10 08:41:56
【问题描述】:

我正在尝试打印“你好,AOP!”每当 Guice/AOP Alliance 截获标有特定(自定义)注释的方法时,消息。我遵循了官方文档(可以在here 找到的 PDF - 第 11 页上的 AOP 方法拦截内容)并且无法使其工作,只能编译。

首先,我的注释:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@BindingAnnotation
public @interface Validating {
    // Do nothing; used by Google Guice to intercept certain methods.
}

然后,我的Module 实现:

public class ValidatingModule implements com.google.inject.Module {
    public void configure(Binder binder) {
        binder.bindInterceptor(Matchers.any(), 
            Matchers.annotatedWith(Validating.class,
            new ValidatingMethodInterceptor()),
    }
}

接下来,我的方法拦截器:

public class ValidatingMethodInterceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("Hello, AOP!");
    }
}

最后,尝试使用所有这些 AOP 东西的驱动程序:

public class AopTest {
    @Validating
    public int doSomething() {
        // do whatever
    }

    public static main(String[] args) {
        AopTest test = new AopTest();

        Injector injector = Guice.createInjector(new ValidatingModule());

        System.out.println("About to use AOP...");

        test.doSomething();
    }
}

当我运行这个小测试驱动程序时,我得到的唯一控制台输出是 About to use AOP......Hello, AOP! 永远不会被执行,这意味着 @Validating doSomething() 方法永远不会像 Guice 文档显示的那样被拦截。

我能想到的唯一的事情是,在我的Module 实现中,我指定要绑定到的MethodInterceptor(作为bindInterceptor 方法的第三个参数)为作为new ValidatingMethodInterceptor(),而在那个拦截器中,我只定义了一个必需的invoke(MethodInvocation) 方法。

也许我没有正确地将这两个连接在一起?也许 Guice 并没有隐含地知道应该在发生拦截时运行 invoke 方法?!?!

再一次,我不仅遵循了 Guice 文档,而且还遵循了其他几个教程,但均无济于事。

我在这里有什么明显的遗漏吗?提前致谢!

编辑 我的代码和我遵循的示例之间的另一个差异虽然很小,但事实上我的 invoke 方法(在拦截器内)没有用 @Override 注释。如果我尝试添加此注释,则会收到以下编译错误:

ValidatingMethodInterceptor 类型的方法 invoke(MethodInvocation) 必须覆盖超类方法。

这个错误是有道理的,因为org.aopalliance.intercept.MethodInterceptor 是一个接口(不是一个类)。再说一次,每个使用 Guice/AOP Alliance 的示例都在 invoke 方法上使用了这个 @Override 注释,所以它显然对某些人有效/编译......很奇怪。

【问题讨论】:

  • 回复:@Override 的事情——一点也不奇怪,它的工作人员正在使用 Java 1.6(或 1.6 源代码合规性),而你没有。

标签: java aop guice


【解决方案1】:

如果你不让 Guice 构造你的对象,它就不能为你提供一个带有拦截器的实例。您不得使用new AopTest() 来获取对象的实例。相反,您必须让 Guice 给您一个实例:

Injector injector = Guice.createInjector(new ValidatingModule ());
AopTest test = injector.getInstance(AopTest.class);

http://code.google.com/p/google-guice/wiki/GettingStarted

【讨论】:

  • 谢谢 JB!快速的问题 - 我的理解是,对 Injector 进行显式调用是一种 IoC 反模式(当我们到达需要AopTest 的地步时,我们应该已经知道它是什么混凝土了)。您的代码示例对我有用(所以谢谢!!!)但是有没有另一种方法来写这个,这样我就不会明确地调用injector.getInstance()?再次感谢!
  • 你必须从某个地方加强依赖注入。您通常只在 main 方法中使用此代码一次来获取根对象。这个根对象被注入其他对象,这些对象被其他对象注入,依此类推。但是必须从注入器中查找对象树的根。
  • @JBNizet 如果我使用AopTestProvider 获取AopTest 实例而不是使用injector.getInstance(AopTest.class),AOP 是否仍然有效?如果不是,是不是here提到的Guice AOP的限制之一!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-08
  • 2015-10-10
  • 1970-01-01
  • 1970-01-01
  • 2011-10-29
  • 1970-01-01
相关资源
最近更新 更多