2011-12-06 20 views
11

¿Hay forma de vincular un interceptor de método a un proveedor en lugar de una instancia?Cómo vincular el interceptor de método al proveedor?

p. Ej. Utilizo el siguiente código para vincular a los interceptores ¿cómo vincularé INTERCEPTOR a un proveedor y luego a la anotación?

bindInterceptor(
    Matchers.any(), Matchers.annotatedWith(ANNOTATION.class), new INTERCEPTOR()); 
+0

¿Qué intentas interceptar? el método get() o quizás algún método setter? –

+0

Bien, cualquier método, idealmente, tenemos un sistema de monitoreo del rendimiento que intercepta las llamadas a los métodos y los tiempos de ejecución, etc. Quiero inicializar el interceptor de forma perezosa. –

Respuesta

18

Guice no permite AOP en instancias no construidos por Guice: Guice AOP Limitations

"Las instancias deben ser creados por Guice por un @ anotados-Inyectar o constructor sin argumentos"

Esto significa que las instancias creadas con un proveedor no serán candidatas para AOP.

Por otro lado, siempre que su proveedor sea creado por Guice en las condiciones mencionadas, su proveedor puede ser candidato para AOP.

Aquí hay un ejemplo que demuestra esto:

AOP Anotación:

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) 
@interface AOPExample {} 

Proveedor:

public class ExampleProvider implements Provider<Example> { 

    @AOPExample 
    public Example get() { 
     System.out.println("Building..."); 
     return new Example(); 
    } 
} 

Ejemplo Objetivo:

public class Example { 

    @AOPExample 
    public void tryMe() { 
     System.out.println("example working..."); 
     try { 
      Thread.sleep(1000L); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

Módulo:

public class ExampleModule extends AbstractModule { 
    @Override 
    protected void configure() { 
     bindInterceptor(Matchers.any(), Matchers.annotatedWith(AOPExample.class), new LoggingAOP()); 

     bind(Example.class).toProvider(ExampleProvider.class); 
    } 
} 

Código de prueba:

public class Test { 

    public static void main(String[] args) { 
     Injector injector = Guice.createInjector(new TestModule()); 

     ExampleProvider exampleProvider = injector.getInstance(ExampleProvider.class); 
     Example example = exampleProvider.get(); 

     example.tryMe(); 

     Example directExample = injector.getInstance(Example.class); 

     directExample.tryMe(); 

    } 
} 

Prueba de salida:

start 
Building... 
end took: 3 
example working... 
start 
Building... 
end took: 0 
example working... 

en cuenta que el "ejemplo de trabajo ..." no está rodeado por el código de temporizador. El Provider.get ("Building ...") es sin embargo.

Si su pregunta es: ¿puede el interceptor (nuevo INTERCEPTOR()) proporcionarse a través de un Proveedor de Guice, la respuesta es no. Lo más cerca que puede llegar a esta funcionalidad es llamar a requestInjection() en el método de configuración del módulo. Esto inyectará su Interceptor con el código apropiado. Desde su interceptor, es posible que pueda utilizar Proveedores para evitar cualquier tipo de sobrecarga que le esté causando lentitud durante el inicio.

Esto es lo que quiero decir:

Módulo:

public class TestModule extends AbstractModule { 
    @Override 
    protected void configure() { 
     bind(String.class).toInstance("One"); 
     bind(String.class).annotatedWith(Names.named("two")).toInstance("Two"); 

     LoggingAOP loggingAOP = new LoggingAOP(); 

     bindInterceptor(Matchers.any(), Matchers.annotatedWith(AOPExample.class), loggingAOP); 

     requestInjection(loggingAOP); 

     bind(Example.class).toProvider(ExampleProvider.class); 
    } 
} 

Interceptor:

public class LoggingAOP implements MethodInterceptor { 

    @Inject 
    private Provider<SomethingThatTakesALongTimeToInit> provider; 

    public Object invoke(MethodInvocation invocation) throws Throwable { 
     provider.get()... 
     System.out.println("start"); 
     long start = System.currentTimeMillis(); 
     Object value = invocation.proceed(); 
     System.out.println("end took: " + (System.currentTimeMillis() - start)); 
     return value; 
    } 
} 

la esperanza que esto responda a su pregunta.

+1

Excelente ejemplo de "Hello World" para Guice AOP. – ripper234

+0

Gracias @ ripper234.Por cierto, tenemos instalaciones similares (casi idénticas) en Transfuse, un proyecto en el que he estado trabajando: http://androidtransfuse.org/documentation.html#method_interceptors –

Cuestiones relacionadas