有沒有辦法將方法攔截器綁定到提供者而不是實例?如何將方法攔截器綁定到提供者?
例如我使用下面的代碼來綁定攔截器如何將INTERCEPTOR綁定到提供者然後綁定到註釋上?
bindInterceptor(
Matchers.any(), Matchers.annotatedWith(ANNOTATION.class), new INTERCEPTOR());
有沒有辦法將方法攔截器綁定到提供者而不是實例?如何將方法攔截器綁定到提供者?
例如我使用下面的代碼來綁定攔截器如何將INTERCEPTOR綁定到提供者然後綁定到註釋上?
bindInterceptor(
Matchers.any(), Matchers.annotatedWith(ANNOTATION.class), new INTERCEPTOR());
吉斯不允許AOP就不會被吉斯內置實例:Guice AOP Limitations
「實例必須由吉斯通過創建@注入註解或無參數的構造」
這意味着,使用提供者創建的實例不會是AOP的候選人。
另一方面,只要您的提供者在上述條件下由Guice實例化,您的提供者就可能成爲AOP的候選者。
以下是一個演示這樣的示例:
AOP譯註:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD)
@interface AOPExample {}
提供者:
public class ExampleProvider implements Provider<Example> {
@AOPExample
public Example get() {
System.out.println("Building...");
return new Example();
}
}
目標示例:
public class Example {
@AOPExample
public void tryMe() {
System.out.println("example working...");
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
模塊:
public class ExampleModule extends AbstractModule {
@Override
protected void configure() {
bindInterceptor(Matchers.any(), Matchers.annotatedWith(AOPExample.class), new LoggingAOP());
bind(Example.class).toProvider(ExampleProvider.class);
}
}
測試代碼:
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();
}
}
測試輸出:
start
Building...
end took: 3
example working...
start
Building...
end took: 0
example working...
注意, 「比如工作......」 是不是由定時器代碼包圍。然而Provider.get(「Building ...」)是。
如果您的問題是:是否可以通過Guice Provider提供攔截器(新的INTERCEPTOR()),答案是否定的。最接近此功能的是調用模塊configure方法中的requestInjection()。這將爲您的Interceptor注入適當的代碼。從攔截器中,您可以使用提供程序來避免任何會導致啓動過程中緩慢的開銷。
這裏就是我的意思是:
模塊:
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);
}
}
攔截:
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;
}
}
希望這回答了你的問題。
偉大的「Hello World」例子給Guice AOP。 – ripper234
謝謝@ ripper234。順便說一下,我們在Transfuse中有類似(幾乎相同)的工具,這是我一直在研究的一個項目:http://androidtransfuse.org/documentation.html#method_interceptors –
你想攔截什麼? get()方法或者一些setter方法? –
那麼理想的任何方法,我們有一個性能監視系統,攔截方法調用和時間他們的執行等。我想懶惰地初始化攔截器。 –