我有这样一个情况,Guice对于某些绑定有效,而对于其他绑定则完全无效。显然我在错误地使用API。
部分原因可能是因为我试图用Guice的方式变得太“花哨”了。我创建了一个
在查看下面的代码之前,请理解我的意图,我的意图是提供可重用的
请注意以下内容:
部分原因可能是因为我试图用Guice的方式变得太“花哨”了。我创建了一个
Module
的继承树,我认为我已经变得太聪明(或愚蠢了!)。在查看下面的代码之前,请理解我的意图,我的意图是提供可重用的
Module
,我可以将其放置在JAR中,并在多个项目之间共享。这个抽象的、可重用的Module
会提供所谓的“默认绑定”,任何实施Module
都会自动遵守这些绑定。例如,一个名为Profiler
的AOPMethodInterceptor
,它查找带有@Calibrated
注释的方法并自动记录执行该方法所需的时间等。请注意以下内容:
@Target({ ElementType.METHOD })
@RetentionPolicy(RetentionPolicy.RUNTIME)
@BindingAnnotation
public @interface Calibrated{}
public class Profiler implement MethodInterceptor {
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
// Eventually it will calculate and log the amount of time
// it takes an intercepted method to execute, hence "Profiler".
System.out.println("Intercepted!");
return arg0.proceed();
}
}
public abstract class BaseModule implements Module {
private Binder binder;
public BaseModule() {
super();
}
public abstract void bindDependencies();
@Override
public void configure(Binder bind) {
// Save the binder Guice passes so our subclasses can reuse it.
setBinder(bind);
// TODO: For now do nothing, down the road add some
// "default bindings" here.
// Now let subclasses define their own bindings.
bindDependencies();
}
// getter and setter for "binder" field
// ...
}
public abstract class AbstractAppModule extends BaseModule {
/* Guice Injector. */
private Injector injector;
// Some other fields (unimportant for this code snippet)
public AbstractAppModule() {
super();
}
// getters and setters for all fields
// ...
public Object inject(Class<?> classKey) {
if(injector == null)
injector = Guice.createInjector(this);
return injector.getInstance(classKey);
}
}
因此,要使用这个小库:
public class DummyObj {
private int nonsenseInteger = -1;
// getter & setter for nonsenseInteger
@Calibrated
public void shouldBeIntercepted() {
System.out.println("I have been intercepted.");
}
}
public class MyAppModule extends AbstractAppModule {
private Profiler profiler;
// getter and setter for profiler
@Override
public void bindDependencies() {
DummyObj dummy = new DummyObj();
dummy.setNonsenseInteger(29);
// When asked for a DummyObj.class, return this instance.
getBinder().bind(DummyObj.class).toInstance(dummy);
// When a method is @Calibrated, intercept it with the given profiler.
getBinder().bindInterceptor(Matchers.any(),
Matchers.annotatedWith(Calibrated.class),
profiler);
}
}
public class TestGuice {
public static void main(String[] args) {
Profiler profiler = new Profiler();
MyAppModule mod = new MyAppModule();
mod.setProfiler(profiler);
// Should return the bounded instance.
DummyObj dummy = (DummyObj.class)mod.inject(DummyObj.class);
// Should be intercepted...
dummy.shouldBeIntercepted();
System.out.println(dummy.getNonsenseInteger());
}
}
这是一大段代码,因此在输入时可能会引入一些打字错误,但我保证这段代码在运行时编译并且不会抛出任何异常。
以下是发生的情况:
@Calibrated shouldBeIntercepted()
方法未被拦截; 但是...- 控制台输出显示虚拟整数为...29!!!
因此,无论您认为这个设计有多差,您都不能否认Guice确实适用于1个绑定(实例绑定),但不适用于AOP方法拦截。
如果实例绑定不起作用,那么我很乐意重新审视我的设计。但是这里还有其他问题。我想知道我的继承树是否会以某种方式影响Binder
?
我已经验证我正确地将拦截器绑定到注释上:我创建了另一个包,在其中只实现了Module
(而不是这个继承树),使用相同的注释、相同的Profiler
,它可以完美地工作。
我使用Injector.getAllBindings()
打印出所有MyAppModule
绑定的映射字符串。没有任何东西浮现出来作为这个错误的明显来源。
new
,因此我实际上并未通过 Guice 获取Dummy
;(2) 由于我随后从非 Guice 注入的Dummy
运行了一个Calibrated
方法,因此 Guice 无法截取它? 如果是这样的话,那就很有道理。 如果不是,请明确一下。 再次感谢您的帮助和出色的答案 (+1)! - IAmYourFaja