有没有办法将方法拦截器绑定(bind)到提供者而不是实例?
例如我使用下面的代码绑定(bind)拦截器,我如何将 INTERCEPTOR 绑定(bind)到提供程序然后绑定(bind)到注释?
bindInterceptor(
Matchers.any(), Matchers.annotatedWith(ANNOTATION.class), new INTERCEPTOR());
最佳答案
Guice 不允许在不是由 Guice 构建的实例上使用 AOP:Guice AOP Limitations
“实例必须由 Guice 通过 @Inject 注释或无参数构造函数创建”
这意味着使用提供者创建的实例将不是 AOP 的候选对象。
另一方面,只要您的 Provider 在上述条件下由 Guice 实例化,您的 Provider 可能是 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...
请注意,“example working...”没有被计时器代码包围。然而,Provider.get ("Building...") 是。
如果您的问题是:是否可以通过 Guice Provider 提供拦截器 (new INTERCEPTOR()),答案是否定的。最接近此功能的方法是在模块配置方法中调用 requestInjection()。这将为您的拦截器注入(inject)适当的代码。从您的拦截器中,您可以使用 Providers 来避免任何导致您在启动过程中变慢的开销。
我的意思是:
模块:
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;
}
}
希望这能回答您的问题。
关于java - 如何将方法拦截器绑定(bind)到提供者?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8406203/