I was trying to create some simple interceptor code, but have
apparently missed some fundamental piece. The binding to the
ExampleImpl happens as expected, but invoke() is never called in the
interceptor. I made this example as minimal as possible, so
hopefully my error will be easy to spot!
/*** Main ***/
public class Bootstrap {
public void startExample() {
Guice.createInjector(new ExampleModule())
.getInstance(Example.class)
.go();
}
public static void main(String[] args) {
new Bootstrap().startExample();
}
}
/*** Module ***/
iimport com.google.inject.AbstractModule;
import static com.google.inject.matcher.Matchers.*;
public class ExampleModule extends AbstractModule {
public void configure() {
bindInterceptor(
any(),
annotatedWith(Interceptable.class),
new ExampleInterceptor());
bind(Example.class)
.to(ExampleImpl.class);
}
}
/*** Interceptor ***/
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class ExampleInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation mi) throws Throwable {
System.out.println("pre-processing in interceptor");
Object o = mi.proceed();
System.out.println("intercepted return value: " + o);
return o;
}
}
/*** Injected class with intercepted method ***/
public class ExampleImpl implements Example {
@Interceptable
public String go() {
System.out.println("processing in ExampleImpl");
return "SUCCESS";
}
}
it should look something like:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Interceptable
{
}
it must have runtime retention, otherwise Guice won't see it.
--
Cheers, Stuart
On May 30, 10:25 pm, "Stuart McCulloch" <mccu...@gmail.com> wrote:
> Can you post your definition of the @Interceptable annotation?
>
> it should look something like:
>
> @Retention(RetentionPolicy.RUNTIME)
> @Target({ElementType.METHOD})
> public @interface Interceptable
> {
> }
>
> it must have runtime retention, otherwise Guice won't see it.
>
This was discussed a while ago in another thread: in Guice 1.0, method
interceptors aren't injected because you pass an existing instance into
bindInterceptor, and this object just gets pushed straight into the proxy.
( at the time you create the interceptor, you don't yet have an injector )
However, there are workarounds, for example - once you've configured
the injector you can use it to go back and inject existing objects using
the injectMembers method, as long as you have a reference to them.
So, what I've done in the past is stash the method interceptor objects
in a field of the module, then I add a method to the module that takes
the injector and uses it to inject the cached interceptors...
For example:
MyModule module = new MyModule();
Injector injector = Guice.createInjector( module );
module.injectInterceptors( injector );
MethodInterceptor injection should be supported in a future version :)
--
Cheers, Stuart