Google Guice、拦截器和 PrivateModules
Posted
技术标签:
【中文标题】Google Guice、拦截器和 PrivateModules【英文标题】:Google Guice, Interceptors and PrivateModules 【发布时间】:2012-03-18 20:37:20 【问题描述】:这里有新海报,希望我不要违反任何规则:)
我在 google-guice 中使用 PrivateModule,以便为同一环境提供多个 DataSource。但是我很难让 MethodInterceptor 在私有模块中工作。 下面是一个解释“问题”的简单测试用例。
一个简单的服务类是:
interface Service
String go();
class ServiceImpl implements Service
@Override @Transactional
public String go()
return "Test Case...";
MyModule
类将是:
class MyModule extends AbstractModule
@Override
protected void configure()
install(new PrivateModule()
@Override
protected void configure()
bind(Service.class).to(ServiceImpl.class);
bindInterceptor(
Matchers.any(),
Matchers.annotatedWith(Transactional.class),
new MethodInterceptor()
@Override
public Object invoke(MethodInvocation i)
throws Throwable
System.out.println("Intercepting: "
+ i.getMethod().getName());
return i.proceed();
);
expose(Service.class);
);
最后的测试用例:
public class TestCase
@Inject Service service;
public TestCase()
Guice.createInjector(new MyModule()).injectMembers(this);
public String go()
return service.go();
public static void main(String[] args)
TestCase t = new TestCase();
System.out.println(t.go());
你会期望输出是:
Intercepting: go
Test Case...
但是没有发生,没有使用拦截器,只输出了antTest Case...
。
如果我绑定/公开ServiceImpl
而不是接口,那么它可以工作。
提前致谢, 问候, LL
【问题讨论】:
【参考方案1】:嗯...我在发布问题后不久就想通了 :)
问题是你还需要expose()
ServiceImpl
类。
所以绑定/暴露将是。
bind(ServiceImpl.class); // ServiceImpl annotated with @Singleton
bind(Service.class).to(ServiceImpl.class);
expose(ServiceImpl.class);
expose(Service.class);
问候, LL
【讨论】:
【参考方案2】:您需要在私有模块中显式绑定 ServiceImpl。您现有代码的问题在于它从父模块继承了 ServiceImpl 的绑定。来自PrivateModule 文档,
私有模块是使用父注入器实现的。当它可以满足它们的依赖关系时,将在根环境中创建即时绑定。此类绑定在树中的所有环境之间共享。
添加这一行应该可以解决问题:
bind(ServiceImpl.class);
【讨论】:
不,这还不够,你还需要暴露绑定,正如我在上一篇文章中所说的。 不!你只需要绑定它。从私有模块中暴露它是不必要的(并且在某种程度上违背了私有模块的观点。)自己测试一下。以上是关于Google Guice、拦截器和 PrivateModules的主要内容,如果未能解决你的问题,请参考以下文章
Guice 学习常量和属性的注入( Constant and Property Inject)
Google Guice 与 JSR-299 CDI / Weld