Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
460 views
in Technique[技术] by (71.8m points)

java - Can't Get Guice Method Interception to Work

I'm trying to print a "Hello, AOP!" message whenever Guice/AOP Alliance intercepts a method marked with a particular (custom) annotation. I have followed the official docs (a PDF that can be found here - AOP method interception stuff on pg. 11) and cannot get it to work, only compile.

First, my annotation:

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

Then, my Module implementation:

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

Next, my method interceptor:

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

Finally, the driver that attempts to make use of all this AOP stuff:

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();
    }
}

When I run this little test driver, the only console output I get is About to use AOP...... the Hello, AOP! never gets executed, which means the @Validating doSomething() method is never being intercepted the way the Guice docs show.

The only thing I can think of is the fact that in my Module implementation I am specifying the MethodInterceptor to bind to (as the 3rd argument to the bindInterceptor method) as being a new ValidatingMethodInterceptor(), whereas in that interceptor, I am only defining a required invoke(MethodInvocation) method.

Perhaps I am not wiring these two together correctly? Perhaps Guice doesn't implicitly know that the invoke method should be ran when an intercept occurs?!?!

Then again, not only have I followed the Guice docs, I have also followed several other tutorials to no avail.

Is there something obvious I am missing here? Thanks in advance!

Edit One other discrepancy between my code and the examples I followed, although small, is the fact that my invoke method (inside the interceptor) is not annotated with @Override. If I try to add this annotation, I get the following compile error:

The method invoke(MethodInvocation) of type ValidatingMethodInterceptor must override a superclass method.

This error makes sense, because org.aopalliance.intercept.MethodInterceptor is an interface (not a class). Then again, every example using Guice/AOP Alliance uses this @Override annotation on the invoke method, so it obviously works/compiles for some people...weird.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you don't let Guice construct your object, it can't provide you an instance with the interceptor wrapped around. You must not use new AopTest() to get an instance of your object. Instead, you must ask Guice to give you one instance:

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

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...