MethodInterceptor is not applied when using @Provides Provier Methods

29 views
Skip to first unread message

thomas....@googlemail.com

unread,
May 21, 2009, 8:58:40 AM5/21/09
to google-guice
Hello,

I just tried to use a MethodInterceptor with a Provider-Method binding
but the method interceptor gets not applied.

When I use the "normal" binding style: bind(Service.class).to
(ServiceImpl.class);
the inteceptor gets applied.

Am I doing something wrong here?

package de.tutorials;

import java.util.Arrays;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Provides;
import com.google.inject.matcher.Matchers;

public class InterceptorIsNotAppliedToProviderMethodBinding {

public static void main(String[] args) {
Injector injector = Guice.createInjector(modules());
Service service = injector.getInstance(Service.class);
service.service();

}

private static Iterable<Module> modules() {
return Arrays.<Module>asList(
// interceptorIsApplied()
// ,
interceptorIsNotApplied()
);
}

private static Module interceptorIsApplied() {
return new AbstractModule(){
protected void configure() {
bind(Service.class).to(ServiceImpl.class);
bindInterceptor(Matchers.subclassesOf(Service.class), Matchers.any
(), tracingInterceptor());
}

};
}

private static Module interceptorIsNotApplied() {
return new AbstractModule(){

@SuppressWarnings("unused")
@Provides Service services(){
return new ServiceImpl();
}

@Override
protected void configure() {
bindInterceptor(Matchers.subclassesOf(Service.class), Matchers.any
(), tracingInterceptor());
}
};
}

protected static MethodInterceptor tracingInterceptor() {
return new MethodInterceptor(){
@Override
public Object invoke(MethodInvocation methodInvocation) throws
Throwable {
System.out.println("About to execute: " +
methodInvocation.getMethod());
return methodInvocation.proceed();
}
};
}

static interface Service{
void service();
}

static class ServiceImpl implements Service{
public void service() {
System.out.println("service");
}
}

}



Best regards,
Thomas

Alen Vrecko

unread,
May 21, 2009, 3:29:00 PM5/21/09
to google-guice
In order for AOP to work Guice needs to create the instance itself
i.e. it must not be created with new. Guice will not just use
constructor on ServiceImpl class but it will first create a new
subclass of ServiceImpl that has the AOP elements in it and use the
constructor on this subclass. But if you create it with new ServiceImpl
() there is no way AOP "elements" can get in.

Cheers,
Alen

On May 21, 2:58 pm, "thomas.darim...@googlemail.com"

thomas....@googlemail.com

unread,
May 21, 2009, 7:58:02 PM5/21/09
to google-guice
Hello,

okay this makes sense :) Thanks!

Best regards,
Thomas



uud ashr

unread,
Jun 9, 2009, 3:26:04 AM6/9/09
to google...@googlegroups.com
Why AOP element can't get in?

Guice has provider and call Object instance = someProvider.get(), guice has the instance.

On spring I can do this.

import org.aopalliance.intercept.MethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;

import org.springframework.aop.framework.ProxyFactory;


public class Hello {

    public void hello() {

        System.out.println("Hello");

    }


    public static void main(String[] args) {

        Hello hello = new Hello();

        ProxyFactory pf = new ProxyFactory(hello);

        pf.addAdvice(new MethodInterceptor() {

            public Object invoke(MethodInvocation invocation) throws Throwable {

                if (invocation.getMethod().getName().equals("hello")) {

                    System.out.println("Intercepting hello");

                }

                Object retVal = invocation.proceed();

                return retVal;

            }

        });

        Hello proxyHello = (Hello)pf.getProxy();

        proxyHello.hello();

    }

}


See. I think we can implement this on Guice. Is it possible? I haven't check the source code yet, but I think this is possible.

Alen Vrecko

unread,
Jun 9, 2009, 7:18:10 AM6/9/09
to google-guice
Well, the way guice handles aop it is not possible for aop elements to
come into a live instance(created via new). That is why using provider
with new doesn't work.

But you're right, aop elements sure can be added. One good thing about
Guice is that it extends easily. You can write a custom provider that
does aop on live instances for you. Something like this http://pastie.org/505566
and do

bind(Foo.class).toProvider(FooProvider.class);

public static class FooProvider extends AopProxingProvider<Foo> {
public Foo getPlain() {
return new Foo();
}
}

Maybe there is a better way. The code is just a suggestion.

Cheers
Alen

Dhanji R. Prasanna

unread,
Jun 9, 2009, 2:06:44 PM6/9/09
to google...@googlegroups.com
Jesse and I were just talking about this the other day. We want to support it with the full set of error checking that Guice provides for in-the-club instances, and there are some gotchas. So it's not as simple as just making it work (for example, what happens when a recursive method is called).

I think we came up with a good solution, that keeps things consistent and gives you the same level of up-front checking but it will take some time to implement.

Dhanji.
Reply all
Reply to author
Forward
0 new messages