Java CDI:在一个“系统”中生成正确的EntityManager的好方法;注射链“;
我有很多servlet,我正在重写它们,从使用PersistenceContext改为使用@inspectedaos 在JSF中,我可以在@products方法中获取对FacesContext的引用,并根据登录用户返回正确的EM(如果登录,则使用默认值,有效用户可用) 当我必须为注入到不同Servlet中的相同DAO生成不同的EMs,并且要注入的EM依赖于启动“注入链”的Servlet时,如何以干净的方式做到这一点 预期成果:Java CDI:在一个“系统”中生成正确的EntityManager的好方法;注射链“;,java,jakarta-ee,servlets,cdi,java-ee-6,Java,Jakarta Ee,Servlets,Cdi,Java Ee 6,我有很多servlet,我正在重写它们,从使用PersistenceContext改为使用@inspectedaos 在JSF中,我可以在@products方法中获取对FacesContext的引用,并根据登录用户返回正确的EM(如果登录,则使用默认值,有效用户可用) 当我必须为注入到不同Servlet中的相同DAO生成不同的EMs,并且要注入的EM依赖于启动“注入链”的Servlet时,如何以干净的方式做到这一点 预期成果: Servlet 1 DaoA
Servlet 1 DaoA EntityM. x
+-----------+ +-----------+ +-----------+
| @Inject | Inject into| @Inject | Inject into| |
| DaoA daoA <-----+------+ E.M. em <------------+ |
| etc | | | //em x | | |
+-----------+ | +-----------+ +-----------+
| DaoB EntityM. x
| +-----------+ +-----------+
| | @Inject | Inject into| |
+------+ E.M. em <------------+ |
| //em x | | |
+-----------+ +-----------+
Servlet 2 DaoA EntityM. y
+-----------+ +-----------+ +-----------+
| @Inject | Inject into| @Inject | Inject into| |
| DaoA daoA <------------+ E.M. em <------------+ |
| | | //em y | | |
+-----------+ +-----------+ +-----------+
我假设当您想在servlet中做出决定时,DAO应该在整个请求中使用相同的实体管理器,因为请求在servlet中开始和结束。换句话说,在服务http请求时,只应使用一个实体管理器 在这种情况下,您可以使用内置的请求作用域和。为EM创建一个producer,该producer的作用域为request,以便每次都使用新请求重新创建它。然后,您可以使用特定的entityManager作为参数触发事件,该参数由您的生产者观察。当生产者接收到事件时,它将存储EM并将其作为生产值返回 执行模式:
EntityManager em
注入servletemEvent
被注入servlet@PostConstruct
中或在服务方法开始时,通过emEvent.fire(em)
EntityManager
- 生产者返回在观察到的事件中接收到的存储实例
EntityManager
@RequestScoped
,@SessionScoped
)。否则,在收到任何事件之前,将调用实体管理器的生产者。但我相信这也适用于你的问题的简单解决方案//In Servlet 1
@PersistenceContext(unitName="x")
EntityManager em;
@Inject
Event<EntityManager> emEvent;
@Inject
Instance<DaoA> daoAInstance;
@Postconstruct
public void postConstruct() {
emEvent.fire(em);
daoAInstance.get().find(...); /* at this point, proper EM will be injected into DaoA.
You should access daoA only after emEvent is fired*/
}
//In Servlet 1
@PersistenceContext(unitName="x")
EntityManager em;
@Inject
Event<EntityManager> emEvent;
@Inject
Instance<DaoA> daoAInstance;
@Postconstruct
public void postConstruct() {
emEvent.fire(em);
daoAInstance.get().find(...); /* at this point, proper EM will be injected into DaoA.
You should access daoA only after emEvent is fired*/
}
// in producer
@RequestScoped (producer will be recreated for every request)
public class DynamicEMProducer {
EntityManager em; /* not injected, but set in observer method.
You may inject a default em if you wish using @PersistenceContext */
// this is handler of event fired in the servlet
public void emChanged(@Observes EntityManager em) {
this.em = em;
}
@Produces
public EntityManager produce() {
return em;
}
}