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