英文:
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);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论