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

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

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

问题

我有以下的Guice模块:

  1. public class GuiceModule {
  2. @Override
  3. protected void configure() {}
  4. @Provides
  5. ClassA classA() {
  6. return new ClassA();
  7. }
  8. @Provides
  9. ClassB classB(ClassA classA) {
  10. ClassB classB = new ClassB(classA);
  11. classB.configure(123)
  12. classB.modify(456);
  13. }
  14. @Provides
  15. ClassC classC(ClassB classB) {
  16. return new ClassC(classB);
  17. }
  18. }

我需要添加以下的bindInterceptor

  1. bindInterceptor(
  2. inSubpackage("my.sub.package"),
  3. annotatedWith(MyAnnotation.class),
  4. classC);

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

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

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

英文:

I have the following Guice module:

  1. public class GuiceModule {
  2. @Override
  3. protected void configure() {}
  4. @Provides
  5. ClassA classA() {
  6. return new ClassA();
  7. }
  8. @Provides
  9. ClassB classB(ClassA classA) {
  10. ClassB classB = new ClassB(classA);
  11. classB.configure(123)
  12. classB.modify(456);
  13. }
  14. @Provides
  15. ClassC classC(ClassB classB) {
  16. return new ClassC(classB);
  17. }
  18. }

I need to add the following bindInterceptor

  1. bindInterceptor(
  2. inSubpackage("my.sub.package"),
  3. annotatedWith(MyAnnotation.class),
  4. 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

  1. 看起来你想要[注入你的拦截器](https://github.com/google/guice/wiki/AOP#injecting-interceptors)。
  2. 你需要稍微不同地编写你的注入器,不使用构造函数注入。
  3. class ClassC {
  4. @Inject
  5. ClassB classB; // 像这样写所有的依赖项。
  6. @Inject
  7. void setClassB(ClassB classB) { this.classB = classB } // 或者像这样
  8. ClassC() { } // 编写任何你可以手动实例化的构造函数
  9. }
  10. 然后在你的 `configure` 方法中:
  11. ClassC classC = new ClassC();
  12. requestInjection(classC);
  13. bindInterceptor(inSubpackage("foo"), annotatedWith(Bar.class), classC);
  14. ---
  15. 由于你无法访问拦截器代码,编写一个封装所需拦截器的自己的代码:
  16. class MyInterceptor implements MethodInterceptor {
  17. ClassC delegate;
  18. @Inject
  19. void inject(ClassB classB) { // 如果需要更多依赖项,你可以将它们作为参数添加在这里,它会正常工作。不为每个依赖项添加一个 setter。
  20. delegate = new ClassC(classB);
  21. }
  22. @Override
  23. public Object invoke(MethodInvocation invocation) throws Throwable {
  24. return delegate.invoke(invocation);
  25. }
  26. }
  27. 现在在你的 configure 方法中使用 `MyInterceptor` 代替 `ClassC`
  28. MyInterceptor interceptor = new MyInterceptor();
  29. requestInjection(interceptor);
  30. 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.

  1. class ClassC {
  2. @Inject
  3. ClassB classB; // Write all dependencies like this.
  4. @Inject
  5. void setClassB(ClassB classB) { this.classB = classB } // Or like this
  6. ClassC() { } // Write any constructor that you can actually instanciate manually
  7. }

Then in your configure method:

  1. ClassC classC = new ClassC();
  2. requestInjection(classC);
  3. 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:

  1. class MyInterceptor implements MethodInterceptor {
  2. ClassC delegate;
  3. @Inject
  4. 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.
  5. delegate = new ClassC(classB);
  6. }
  7. @Override
  8. public Object invoke(MethodInvocation invocation) throws Throwable {
  9. return delegate.invoke(invocation);
  10. }
  11. }

Now use MyInterceptor instead of ClassC in your configure method:

  1. MyInterceptor interceptor = new MyInterceptor();
  2. requestInjection(interceptor);
  3. 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:

确定