java - 如何将方法拦截器绑定(bind)到提供者?

标签 java guice

有没有办法将方法拦截器绑定(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/

相关文章:

java - 如何在 tomcat 服务器的 "display name"列中显示应用程序名称?

java8 orElse(null.getValue()) 如何处理

Scala Play Guice 依赖注入(inject)失败

guice - 在哪里可以找到 @Guice 注释

unit-testing - Guice:为什么@Singleton-annotated 类必须是不可变的/线程安全的?

java - 在java中生成随机双数的最快方法

java - 为什么我的绘图面板在调整窗口大小时有时会绘画而有时不会?

java - Spark的scala代码如何暴露为Java API?

java - Guice:注入(inject)由另一个模块绑定(bind)的类?

java - Google GIN、GWT 和 com.google.inject.Inject(可选=true)不起作用