对于丰富的域驱动设计,我想使用对JPA/Hibernate实体bean的Guice依赖注入。我正在寻找一个类似于非Spring bean的Spring @configurable注释的解决方案。实体bean的Guice依赖注入?
有人知道图书馆吗?任何代码示例?
对于丰富的域驱动设计,我想使用对JPA/Hibernate实体bean的Guice依赖注入。我正在寻找一个类似于非Spring bean的Spring @configurable注释的解决方案。实体bean的Guice依赖注入?
有人知道图书馆吗?任何代码示例?
你可以用AspectJ做到这一点。
创建@Configurable注解:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Configurable {
}
创建一个AspectJ @Aspect与此类似:
@Aspect
public class ConfigurableInjectionAspect {
private Logger log = Logger.getLogger(getClass().getName());
@Pointcut("@within(Configurable) && execution(*.new(..)) && target(instantiated)")
public void classToBeInjectedOnInstantiation(Object instantiated) {}
@After(value = "classToBeInjectedOnInstantiation(instantiated)",
argNames = "instantiated")
public void onInstantiation(Object instantiated) {
Injector injector = InjectorHolder.getInjector();
if (injector == null) {
log.log(Level.WARNING, "Injector not available at this time");
} else {
injector.injectMembers(instantiated);
}
}
}
创建(和使用)控股类的喷油器:
public final class InjectorHolder {
private static Injector injector;
static void setInjector(Injector injector) {
InjectorHolder.injector = injector;
}
public static Injector getInjector() {
return injector;
}
}
配置META-INF/aop.xml:
<aspectj>
<weaver options="-verbose">
<include within="baz.domain..*"/>
<include within="foo.bar.*"/>
</weaver>
<aspects>
<aspect name="foo.bar.ConfigurableInjectionAspect"/>
</aspects>
</aspectj>
与aspectjweaver启动VM:
-javaagent:lib/aspectjweaver.jar
注释域类:
@Entity
@Table(name = "Users")
@Configurable
public class User {
private String username;
private String nickname;
private String emailAddress;
@Inject
private transient UserRepository userRepository
public User() {}
}
由于实体是由JPA提供者创建的,所以我没有看到Guice何时会进场。也许看看Salve项目的方法。
我发现这个问题有点脏的解决方法。
假设仅存在两种方法来创建T
类型的实体对象:
javax.inject.Provider<T>
@PostLoad
注解的方法)Quering它。此外,假设您拥有所有实体的基础结构基类,那么您可以将实体监听器添加到此实体中。在这个例子中,我使用静态注入 - 也许有更好的方法。
@MappedSuperclass
public abstract class PersistentDomainObject<K extends Serializable & Comparable<K>>
implements Comparable<PersistentDomainObject<K>>, Serializable {
private static transient Injector injector;
@PostLoad
private final void onAfterLoaded() {
injector.injectMembers(this);
}
@EmbeddedId
private K id;
public K getId() { return id; }
// ... compareTo(), equals(), hashCode(), maybe a @Version member ...
}
在你的模块设置,您只需要调用requestStaticInjection(PersistentDomainObject.class);
现在,你根本就创建一个像
@Entity
public class MyDomainEntity extends PersistentDomainObject<SomeEmbeddableIdType>
implements HatLegacyId {
@Inject
private transient MyDomainService myDomainService;
private String name;
// ... common stuff
}
它坏事实体类,你必须在没有人相信会创造一个MyDomainEntity
自己,但会要求Provider<MyDomainEntity>
。这可以通过隐藏构造函数来提供。
亲切的问候,
AVI
即使静态注入在某种程度上不鼓励,添加依赖像AspectJ目前不适合我的项目。此外,解决方案适合我的问题,相当干净。 – Iacopo 2012-09-10 10:32:53
谢谢,像药膏一个codeweaving解决方案可以真正做的伎俩。我尝试过Salve,但是它的文档有限,我无法做任何事情(甚至没有错误信息)。只希望一些简单的示例代码,例如使用AspectJ或更好的AOP。 – Kdeveloper 2010-07-18 05:13:59
@Kdeveloper:我对Salve没有任何经验,所以我不推荐它,但它可能会给你一些想法来实现类似的东西,这就是为什么我提到它 – 2010-07-19 13:26:50