Guice方法拦截器不起作用

3

注解

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

拦截器
public class PublishMetricInterceptor implements MethodInterceptor {
  @Override
  public Object invoke(MethodInvocation methodInvocation) throws Throwable {
    System.out.println("invoked");
    return methodInvocation.proceed();
  }
}

Guice 模块

public class MetricsModule extends AbstractModule {
  @Override
  protected void configure() {
    bindInterceptor(any(), annotatedWith(PublishMetric.class), new PublishMetricInterceptor());
  }

  @Provides
  @Singleton
  public Dummy getDummy(Client client) {
    return new Dummy(client);
  }
}

使用方法

public class Dummy {
  private final Client client;

  @Inject
  public Dummy(final Client client) {
    this.client = client;
  }

  @PublishMetric
  public String something() {
    System.out.println("something");
  }
}

我不确定为什么这个拦截器不起作用。 Guice AOP Wiki 指出:

实例必须由 Guice 通过一个 @Inject-annotated 或无参数构造函数创建。无法在不是由 Guice 构造的实例上使用方法拦截。

使用 @Provides 注释创建新对象是否被视为由 Guice 创建的实例?

1个回答

8
您的引述是正确的:“无法在不由Guice构造的实例上使用方法拦截。”因此,由于您在提供方法中调用了“new Dummy()”,它将无法工作。如果您使用
  bind(Dummy.class).asEagerSingleton();

它确实如此。


是的,你分享的例子中不需要 @Provides,因为 Client 也是一个被注入的依赖项,Guice 会为你处理!此外,如果要使该类成为单例,可以在类声明中添加 @Singleton 注解。 - Harish
那么我可以使用@Provides来实例化客户端依赖关系吗,因为它不需要方法拦截器? - Vaishal
很抱歉,我不太明白你的问题。在Dummy类中使用的Client是一个依赖项,因为你已经用@Inject注解了Dummy类的构造函数,并且Client client是它唯一的参数。像其他任何依赖项一样,你可以在你的Guice模块中指定类型Client的绑定,这也可以使用@Provides来实现。 - Harish
这对我来说有些违反直觉,@Provides 应该用于定义 Guice 返回的构造对象,而使用 bind 应该更适合于模块中的接口类绑定吧? - Pievis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接