使用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,那么管理器字段为null
但是,如果我没有标记@Stat,我可以注入管理器字段,并且该应用程序可以将数据保存到DB中,因此该应用程序可以使用。
只是想知道,这背后的原因是什么?
这是接线应用程序的首选方法吗?
好吧,我正在考虑将实体管理员拿到生产者,以便可以共享
解决方案
问题是,如果我不将userService标记为@stateless,那么管理器字段为null
要进行注射,课程必须是 托管组件 例如企业豆,servlet,过滤器,JSF托管豆等或 CDI托管豆 (这是Java EE 6的新部分,您可以将任何类带有CDI托管的bean制作)。
因此,如果您不将JAX-RS端点变成EJB,那么如何启用注射?这很好地解释了 使用Glassfish V3的JAX-RS和CDI集成:
CDI托管豆的启用有两种方式:
由CDI实例化,由泽西岛管理的生命周期。注释
@ManagedBean
并可选地用泽西镜注释注释。由CDI实例化和管理。用CDI示波器注释注释,
@RequestScoped
(不@ManagedBean
是必须的)
我还建议检查以下资源。
这是接线应用程序的首选方法吗?
我会说是的。 CDI非常好,...您不喜欢注射吗?
好吧,我正在考虑将实体管理员拿到生产者,以便可以共享
什么之间分享?为什么?在您的情况下,您应该使用 EntityManager
寿命范围为单个交易(a 交易的持久性上下文)。换句话说,不要共享它(不必担心为每个请求打开和关闭它,这不是一个昂贵的操作)。
参考
- JPA 2.0规范
- 第7.6节“由容器管理的持久性上下文”
- 7.6.1节“容器管理的交易持续性上下文”
- 第7.6.2节“由容器管理的扩展持久性上下文”
资源
其他提示
这 @singleton 注释将有所帮助: http://www.mentby.com/paul-sandoz/jax-rs-on-glassfish-31-ejb-injection.html