對於豐富的域驅動設計,我想使用對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