我想弄清楚如何處理CDI。我正在研究一個用戶可以連接到多個數據庫的應用程序。應用程序詢問他們想要連接到哪一個,並且它們也可以斷開並連接到不同的數據庫。這是一個使用Seam for CDI和Hibernate for JPA的Java SE應用程序。我試圖弄清楚的是,如何利用CDI來連接@PersistenceContext,同時使它動態變化,以便訪問不同的數據庫。我只是不確定我會用CDI做這種模式或技術。思考?CDI根據用戶輸入注入@PersistenceContext
2
A
回答
2
所以我想我找到了我想要的東西用javax.enterprise.inject.Instance
做。首先定義一個簡單的bean:
@Alternative
public class Foo {
private int value;
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
它被定義爲一個@Alternative
所以CDI沒有得到這個和生產者方法(下示出)之間相混淆。一個更好的解決方案是將Foo
定義爲接口,然後FooImpl
將被註釋爲@Typed
,所以CDI認爲它只是一個FooImpl
bean類型。無論如何,接下來是生產者階層。
@ApplicationScoped
public class FooProducer {
private int value;
public FooProducer() {
value = -1;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
@Produces
public Foo getFoo() {
Foo p = new Foo();
p.setValue(getValue());
return p;
}
}
getFoo()
該方法產生具有不同值的新Foo
對象。該值可以通過setValue(int)
方法進行更改。接下來我使用javax.enterprise.inject.Instance
來注入Foo
。
@Inject
Instance<Foo> fooInstance;
@Inject
FooProducer fooProducer;
....
fooProducer.setValue(10);
Foo foo = fooInstance.get();
System.out.printf("foo = %s, %d\n", foo.getValue());
fooProducer.setValue(10000);
foo = fooInstance.get();
System.out.printf("foo = %s, %d\n", foo.getValue());
這裏我用的注射fooProducer.setValue()
方法來改變生產者將如何產生Foo
。當fooInstance.get()
被稱爲第一次Foo
將包含值10,第二次就會產生價值10000
鑑於這個簡單的例子,很容易適用於在運行時獲得EntityManager
實例到不同的數據庫。產生EntityManager
的代碼還有一些,但不是太多。
0
PersistenceContext由EJB容器處理。由於您不在EJB容器中,因此請忘記持久性上下文並考慮使用CDI生產者。
@ApplicationScoped
public class EntityManagerFactoryProvider {
private EntityManagerFactory emf;
public void voidApplicationEMF() {
//load the EMF here based on dynamic properties
this.emf = Persistence.createEntityManagerFactpry(Map of loaded properties);
}
@Produces
public EntityManager em() {
return emf.createEntityManager();
}
}
在你的代碼
@SessionScoped
public class MyEntityController {
@Inject
private EntityManager emf;
}
然後某處還有處理事務等
在JSE環境中,必須明確地啓動和提交/回滾事務的問題。 由於您正在使用CDI,因此您可以使用Interceptors根據需要開始/檢查事務狀態並進行回滾/提交。
@Interceptor
public class MyInterceptor {
@Inject
private EntityManager em;
@AroundInvoke
public Object intercept(InvocationContext ic) {
try {
//initiate transaction
em.getTransaction().start ....
return ic.proceed();
}catch(Exception ex) { //rollback if necessary }
finally {//commit transaction if necessary }
}
}
相關問題
- 1. (Laravel)動態依賴注入的界面,根據用戶輸入
- 2. 將CDI注入FacesConverter
- 3. CDI注入循環
- 4. CDI通用DAO注入
- 5. CDI注入和@Model註釋
- 6. 根據用戶輸入在輸入字段中顯示數據
- 7. Java CDI與Tomcat的PersistenceContext 8
- 8. 根據ArrayList驗證用戶輸入
- 9. 根據用戶輸入創建URL
- 10. 根據用戶輸入確定顏色
- 11. 根據用戶輸入確認日期
- 12. 根據用戶輸入按行回顯
- 13. 根據用戶輸入選擇行
- 14. 根據用戶輸入選擇子類?
- 15. 根據用戶輸入sturct intitiatlization:
- 16. 根據用戶輸入限制字數
- 17. 根據用戶輸入創建文件
- 18. 根據用戶輸入安排工作
- 19. 如何將@PersistenceContext注入pojo類
- 20. 根據用戶輸入擴展數量Html輸入寬度?
- 21. 根據用戶輸入創建輸入數量(帶前綴)
- 22. MySQL的信息輸入到表中根據用戶輸入
- 23. 根據用戶輸入添加其他輸入字段
- 24. 如何根據用戶輸入更改顯示錶輸入
- 25. 根據用戶輸入的輸入字段沒有
- 26. @RequestScoped CDI注入到@MessageDriven bean
- 27. CDI跨容器注入
- 28. CDI依賴注入問題
- 29. CDI注入Hibernate的實體
- 30. 遺產和CDI注入
> PersistenceContext由EJB容器處理 - 這是不正確的。 JPA是EJB的一個獨立規範,持久化上下文通常由JPA實現的Java EE容器特定部分設置。 – 2014-09-30 07:04:13
@ArjanTijms實際上JPA規範是EJB規範的一部分,只有規範文檔是分開的 – maress 2014-09-30 07:09:16
我不清楚如何實現您評論的部分爲「//根據動態屬性在這裏加載EMF」我不想要生產者類負責用戶界面。我試圖找出MVC的方式 - 該視圖處理獲取動態信息然後以某種方式將其傳遞給製作人。現在我在打字的時候正在考慮這個問題,也許CDI活動是要走的路?生產者類觀察一個事件並在生成EntityManager時使用的生產者類中設置動態數據?數據庫更改時注入點如何更新? – 2014-09-30 15:22:56