使用 CDI + WS/RS + JPA 构建应用程序

发布于 2024-09-24 15:55:11 字数 886 浏览 0 评论 0原文

@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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

伴随着你 2024-10-01 15:55:11

问题是如果我不将 UserService 标记为 @Stateless 那么管理器字段为 null

为了发生注入,该类必须是一个托管组件,例如 Enterprise Beans、Servlet、Filters、JSF 托管 bean等或CDI托管bean(这是Java EE 6的新部分,您可以使用CDI使任何类成为托管bean)。

那么,如果您不将 JAX-RS 端点设置为 EJB,如何启用注入? 使用 Glassfish v3 的 JAX-RS 和 CDI 集成对此进行了很好的解释:

CDI管理bean有两种方式
已启用:

  1. 由 CDI 实例化,生命周期由 Jersey 管理。注释为
    @ManagedBean 并可选择注释
    带有 Jersey 范围注释。

  2. 由 CDI 实例化和管理。使用 CDI 范围注释进行注释,
    像@RequestScoped(没有@ManagedBean)
    为必填项)

我还建议检查以下资源。

这是连接应用程序的首选方式吗?

我会说是的。 CDI 非常好,而且...您不喜欢注射吗?

嗯,我正在考虑将 EntityManager 拉出给生产者,以便可以共享

在什么之间共享?为什么?在您的情况下,您应该使用生命周期限于单个事务(事务范围的持久性上下文)的 EntityManager。换句话说,不要共享它(并且不必担心为每个请求打开和关闭它,这不是一个昂贵的操作)。

参考

  • JPA 2.0 规范
    • 第 7.6 节“容器管理的持久性上下文”
    • 第 7.6.1 节“容器管理的事务范围持久性上下文”
    • 第 7.6.2 节“容器管理的扩展持久性上下文”

资源

the problem is if I do not mark UserService as @Stateless then the manager field is null

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:

There are two ways CDI managed beans
are enabled:

  1. instantiated by CDI, life-cycle managed by Jersey. Annotate with
    @ManagedBean and optionally annotate
    with a Jersey scope annotation.

  2. instantiated and managed by CDI. Annotate with a CDI scope annotation,
    like @RequestScoped (no @ManagedBean
    is required)

I also suggest checking the resources below.

and is this the preferred way to wiring the application?

I'd say yes. CDI is very nice and... don't you like injection?

well, I am thinking to pull out the EntityManager to a producer, so that it can be shared

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

  • JPA 2.0 Specification
    • Section 7.6 "Container-managed Persistence Contexts"
    • Section 7.6.1 "Container-managed Transaction-scoped Persistence Context"
    • Section 7.6.2 "Container-managed Extended Persistence Context"

Resources

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文