如何在Google Guice中绑定拦截器,当拦截器没有默认构造函数时?

huangapple go评论70阅读模式
英文:

How can I bindInterceptor in Google Guice when the Interceptor does not have a default constructor?

问题

我有以下的Guice模块:

public class GuiceModule {
    @Override
    protected void configure() {}

    @Provides
    ClassA classA() {
        return new ClassA();
    }

    @Provides
    ClassB classB(ClassA classA) {
        ClassB classB = new ClassB(classA);
        classB.configure(123)
        classB.modify(456);
    }

    @Provides
    ClassC classC(ClassB classB) {
        return new ClassC(classB);
    }
}

我需要添加以下的bindInterceptor

bindInterceptor(
    inSubpackage("my.sub.package"),
    annotatedWith(MyAnnotation.class),
    classC);

我只能从configure()方法中调用bindInterceptor,基于这个文件的第140行。

除了不使用@Provides方法,而是在configure方法中完成所有操作外,我还有哪些选项?

**注意:**我不拥有ClassA、ClassB或ClassC。它们都来自第三方包。

英文:

I have the following Guice module:

public class GuiceModule {
    @Override
    protected void configure() {}

    @Provides
    ClassA classA() {
        return new ClassA();
    }

    @Provides
    ClassB classB(ClassA classA) {
        ClassB classB = new ClassB(classA);
        classB.configure(123)
        classB.modify(456);
    }

    @Provides
    ClassC classC(ClassB classB) {
        return new ClassC(classB);
    }
}

I need to add the following bindInterceptor

bindInterceptor(
    inSubpackage("my.sub.package"),
    annotatedWith(MyAnnotation.class),
    classC);

I can only call bindInterceptor from the configure() method, based on Line 140 of this file.

What other options do I have besides not using @Provides methods and instead doing everything in the configure method?

Note: I don't own ClassA, ClassB, or ClassC. They all come from a third party package.

答案1

得分: 3

看起来你想要[注入你的拦截器](https://github.com/google/guice/wiki/AOP#injecting-interceptors)。

你需要稍微不同地编写你的注入器,不使用构造函数注入。

class ClassC {
  @Inject
  ClassB classB;                                         // 像这样写所有的依赖项。
  @Inject
  void setClassB(ClassB classB) { this.classB = classB } // 或者像这样

  ClassC() { } // 编写任何你可以手动实例化的构造函数
}

然后在你的 `configure` 方法中:

ClassC classC = new ClassC();
requestInjection(classC);
bindInterceptor(inSubpackage("foo"), annotatedWith(Bar.class), classC);

---
由于你无法访问拦截器代码,编写一个封装所需拦截器的自己的代码:

class MyInterceptor implements MethodInterceptor {
  ClassC delegate;
  
  @Inject
  void inject(ClassB classB) { // 如果需要更多依赖项,你可以将它们作为参数添加在这里,它会正常工作。不为每个依赖项添加一个 setter。
    delegate = new ClassC(classB);
  }
  
  @Override
  public Object invoke(MethodInvocation invocation) throws Throwable {
    return delegate.invoke(invocation);
  }
}

现在在你的 configure 方法中使用 `MyInterceptor` 代替 `ClassC`:

MyInterceptor interceptor = new MyInterceptor();
requestInjection(interceptor);
bindInterceptor(inSubpackage("foo"), annotatedWith(Bar.class), interceptor);
英文:

It looks like you want to inject your interceptors.

You have to write your injectors slightly differently and not use the constructor injection.

class ClassC {
  @Inject
  ClassB classB;                                         // Write all dependencies like this.
  @Inject
  void setClassB(ClassB classB) { this.classB = classB } // Or like this

  ClassC() { } // Write any constructor that you can actually instanciate manually
}

Then in your configure method:

ClassC classC = new ClassC();
requestInjection(classC);
bindInterceptor(inSubpackage("foo"), annotatedWith(Bar.class), classC);

Since you don't have access to the interceptor code, write your own that encapsulate the one you want:

class MyInterceptor implements MethodInterceptor {
  ClassC delegate;
  
  @Inject
  void inject(ClassB classB) { // If more dependencies are required, you can add them as parameter here, it'll just work. Don't add a setter per dependency.
    delegate = new ClassC(classB);
  }
  
  @Override
  public Object invoke(MethodInvocation invocation) throws Throwable {
    return delegate.invoke(invocation);
  }
}

Now use MyInterceptor instead of ClassC in your configure method:

MyInterceptor interceptor = new MyInterceptor();
requestInjection(interceptor);
bindInterceptor(inSubpackage("foo"), annotatedWith(Bar.class), interceptor);

huangapple
  • 本文由 发表于 2020年8月21日 08:55:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/63515074.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定