我正在寻找关于如何将运行时依赖注入到从Hibernate检索的JPA实体中的建议。我的问题本质上是这样的:需要模式建议(Hibernate + Guice)
我有一些交易对象的不同子类。每个Transaction子类在执行时都有不同的行为,并且需要来自环境的一组不同的依赖关系。这些Transaction对象由Hibernate作为JPA实体进行管理,因此我无法有效地使用Guice进行依赖注入,以便像我在其他应用程序中那样使用它们的环境依赖项来填充实例。
要解决这个问题,我已经采取了一个办法,就是有点类似访问者模式,如下:
public abstract class Transaction {
// ...snip...
public abstract void apply(Transactor transactor);
}
public class TransactionA extends Transaction {
public void apply(Transactor transactor) {
transactor.execute(this);
}
}
public class TransactionB extends Transaction {
public void apply(Transactor transactor) {
transactor.execute(this);
}
}
// other Transaction subclasses with the same boilerplate
public interface Transactor {
public void execute(TransactionA trans);
public void execute(TransactionB trans);
// corresponding methods for other transaction types.
}
public class BeginTransactor {
@Inject
private Foo execAdep;
public void execute(TransactionA trans) {
execAdep.doSomething(...)
}
@Inject
private Bar execBdep;
public void execute(TransactionB trans) {
execBdep.doOther(...)
}
}
我有一个交易周期的不同部分的交易者的各种实现方式。这些可以是依赖注入使用吉斯到我要处理的事务,在这里我简单的调用上下文:
Transactor transactor = injector.getInstance(BeginTransactor.class); //Guice injection
Transaction t = ... //get a transaction instance
t.apply(transactor);
我不喜欢这种方法是什么(1)不是每个类型的交易应该在每个生命周期阶段都可执行,但每个Transactor必须为每个事务子类实现一个execute()方法,并且(2)基本上没有一个注入的依赖项用于处理多个事务类型。
本质上,我的Transactor接口&实现了很多不相干的crud glopped在一起。理想情况下,我只需在事务对象本身拥有execute()方法,但我不希望调用代码必须知道事务的类型或它需要的依赖关系。另外,这可能会使测试变得更加困难,因为如果它是Transaction对象的具体方法,我不能轻易地模拟出execute()方法。使用Transactor接口意味着我可以根据需要轻松地嘲笑它。
任何人都可以建议如何解决这个问题的类型安全的方式,不会导致一堆大多数不相关的行为一起在Transactor中一起出现,但保持可测试性并允许依赖注入?
非常好,谢谢!我曾怀疑可能有AOP方法解决这个问题,但并不确定如何去解决这个问题。 – 2008-12-17 16:19:04