使用 CDI + WS/RS + JPA 构建应用程序
@Path(value = "/user")
@Stateless
public class UserService {
@Inject
private UserManager manager;
@Path(value = "/create")
@GET
@Produces(value = MediaType.TEXT_PLAIN)
public String doCreate(@QueryParam(value = "name") String name) {
manager.createUser(name);
return "OK";
}
}
这是用户管理器实现,
public class UserManager {
@PersistenceContext(unitName = "shop")
private EntityManager em;
public void createUser(String name) {
User user = new User();
user.setName(name);
// skip some more initializations
em.persist(user);
}
}
问题是如果我不将 UserService 标记为@Stateless,则管理器字段为空,
但如果我标记@Stateless,我可以注入管理器字段,并且应用程序可以正常工作,因为我可以保存数据进入 db
只是想知道,这背后的原因是什么?
这是连接应用程序的首选方式吗?
好吧,我正在考虑将 EntityManager 拉出给生产者,以便可以共享
@Path(value = "/user")
@Stateless
public class UserService {
@Inject
private UserManager manager;
@Path(value = "/create")
@GET
@Produces(value = MediaType.TEXT_PLAIN)
public String doCreate(@QueryParam(value = "name") String name) {
manager.createUser(name);
return "OK";
}
}
here is the user manager impl
public class UserManager {
@PersistenceContext(unitName = "shop")
private EntityManager em;
public void createUser(String name) {
User user = new User();
user.setName(name);
// skip some more initializations
em.persist(user);
}
}
the problem is if i do not mark UserService as @Stateless then the manager field is null
but if i mark @Stateless, i can have the manager field injected, and the application works as i can get the data saved into db
just wondering, what is the reason behind this?
and is this the preferred way to wiring the application?
well, i am thinking to pull out the EntityManager to a producer, so that it can be shared
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了发生注入,该类必须是一个托管组件,例如 Enterprise Beans、Servlet、Filters、JSF 托管 bean等或CDI托管bean(这是Java EE 6的新部分,您可以使用CDI使任何类成为托管bean)。
那么,如果您不将 JAX-RS 端点设置为 EJB,如何启用注入? 使用 Glassfish v3 的 JAX-RS 和 CDI 集成对此进行了很好的解释:
我还建议检查以下资源。
我会说是的。 CDI 非常好,而且...您不喜欢注射吗?
在什么之间共享?为什么?在您的情况下,您应该使用生命周期限于单个事务(事务范围的持久性上下文)的
EntityManager
。换句话说,不要共享它(并且不必担心为每个请求打开和关闭它,这不是一个昂贵的操作)。参考
资源
For injection to occur, the class has to be a managed component such as Enterprise Beans, Servlets, Filters, JSF managed beans, etc or CDI managed bean (this is the new part with Java EE 6, you can make any class a managed bean with CDI).
So, if you don't make your JAX-RS endpoint an EJB, how to enable injection? This is nicely explained in JAX-RS and CDI integration using Glassfish v3:
I also suggest checking the resources below.
I'd say yes. CDI is very nice and... don't you like injection?
Shared between what? And why? In you case, you should use an
EntityManager
with a lifetime that is scoped to a single transaction (a transaction-scoped persistence context). In other words, don't share it (and don't worry about opening and closing it for each request, this is not an expensive operation).References
Resources
@Singleton 注释将有所帮助:http://www.mentby.com/paul-sandoz/jax-rs-on-glassfish-31-ejb-injection.html
The @Singleton annotation will help: http://www.mentby.com/paul-sandoz/jax-rs-on-glassfish-31-ejb-injection.html