什么时候需要或方便地使用 Spring 或 EJB3 或它们一起使用? [英] When is it necessary or convenient to use Spring or EJB3 or all of them together?

查看:17
本文介绍了什么时候需要或方便地使用 Spring 或 EJB3 或它们一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 JSF2+Spring+EJB3 或它们的任意组合的混合使用感到有些困惑.我知道 Spring 的主要特征之一是依赖注入,但是对于 JSF 托管 bean,我可以使用 @ManagedBean@ManagedProperty 注释,并且我可以获得依赖注入功能.对于 EJB3,我更困惑于何时将它与 JSF 一起使用,或者是否有理由使用它.

I'm a little confused by the mixed use of JSF2+Spring+EJB3 or any combination of those. I know one of the Spring principal characteristics is dependency injection, but with JSF managed beans I can use @ManagedBean and @ManagedProperty anotations and I get dependency injection functionality. With EJB3 I'm even more confused about when to use it along with JSF or if there is even a reason to use it.

那么,在什么样的情况下使用Spring+JSF2或EJB3+JSF2比较好?

So, in what kind of situation would it be a good idea to use Spring+JSF2 or EJB3+JSF2?

到现在为止,我只使用 JSF2 创建了一些小型 Web 应用程序,而从不需要使用 Spring 或 EJB3.但是,我在很多地方看到人们正在一起使用所有这些东西.

Until now I have created just some small web applications using only JSF2 and never needed to use Spring or EJB3. However, I'm seeing in a lot of places that people are working with all this stuff together.

推荐答案

首先,Spring 和 EJB(+JTA) 是相互竞争的技术,通常不会在同一个应用程序中一起使用.选择其中之一.Spring EJB(+JTA).我不会告诉你选择哪个,我只会告诉你一些历史和事实,以便你更容易做出决定.

First of all, Spring and EJB(+JTA) are competing technologies and usually not to be used together in the same application. Choose the one or the other. Spring or EJB(+JTA). I won't tell you which to choose, I will only tell you a bit of history and the facts so that you can easier make the decision.

他们试图解决的主要问题是提供具有自动事务管理功能的业务服务层 API.想象一下,您需要触发多个 SQL 查询来执行单个业务任务(例如下订单),并且其中一个失败了,那么您当然希望 一切 都回滚,以便DB 保持与之前相同的状态,就好像完全没有发生过一样.如果您不使用事务,那么数据库将处于无效状态,因为第一组查询实际上成功了.

Main problem they're trying to solve is providing a business service layer API with automatic transaction management. Imagine that you need to fire multiple SQL queries to perform a single business task (e.g. placing an order), and one of them failed, then you would of course like that everything is rolled back, so that the DB is kept in the same state as it was before, as if completely nothing happened. If you didn't make use of transactions, then the DB would be left in an invalid state because the first bunch of the queries actually succeeded.

如果您熟悉基本的 JDBC,那么您应该知道这可以通过关闭连接上的自动提交,然后按顺序触发这些查询,然后在非常相同的 try 在其 catch (SQLException) 中执行了 rollback().然而这是相当每次都实施起来很乏味.

If you're familiar with basic JDBC, then you should know that this can be achieved by turning off autocommit on the connection, then firing those queries in sequence, then performing commit() in the very same try in whose catch (SQLException) a rollback() is performed. This is however quite tedious to implement everytime.

使用 Spring 和 EJB(+JTA),默认情况下,单个(无状态)业务服务方法调用作为单个完整事务透明地计数.这样你就完全不用担心事务管理了.您不需要手动创建 EntityManagerFactory,也不需要显式调用 em.getTransaction().begin() ,就像您在紧耦合业务服务时所做的那样逻辑到 JSF 支持 bean 类和/或在 JPA 中使用 RESOURCE_LOCAL 而不是 JTA.例如,您可以使用 JPA 仅使用以下 EJB 类:

With Spring and EJB(+JTA), a single (stateless) business service method call counts by default transparently as a single full transaction. This way you don't need to worry about transaction management at all. You do not need to manually create EntityManagerFactory, nor explicitly call em.getTransaction().begin() and such as you would do when you're tight-coupling business service logic into a JSF backing bean class and/or are using RESOURCE_LOCAL instead of JTA in JPA. You could for example have just the following EJB class utilizing JPA:

@Stateless
public class OrderService {

    @PersistenceContext
    private EntityManager em;

    @EJB
    private ProductService productService;

    public void placeOrder(Order newOrder) {
        for (Product orderedproduct : newOrder.getProducts()) {
            productService.updateQuantity(orderedproduct);
        }

        em.persist(newOrder);
    }

}

如果您的 JSF 支持 bean 中有一个 @EJB 私有 OrderService orderService; 并在 action 方法中调用 orderService.placeOrder(newOrder);,那么单个将执行完整的交易.例如,如果 updateQuantity() 调用之一或 persist() 调用失败并出现异常,那么它将回滚到目前为止执行的任何 updateQuantity() 调用,并使数据库保持干净清晰的状态.当然,您可以在 JSF 支持 bean 中捕获该异常并显示一个 faces 消息左右.

If you have a @EJB private OrderService orderService; in your JSF backing bean and invoke the orderService.placeOrder(newOrder); in the action method, then a single full transaction will be performed. If for example one of the updateQuantity() calls or the persist() call failed with an exception, then it will rollback any so far executed updateQuantity() calls, and leave the DB in a clean and crisp state. Of course, you could catch that exception in your JSF backing bean and display a faces message or so.

应注意的是Spring"是一个相当大的框架,不仅可以与 EJB 竞争,还可以与 CDI 和 JPA 竞争.以前,在黑暗的 J2EE 时代,EJB 2.x 的实现极其糟糕(上面的 EJB 3.x OrderService 示例在 EJB 2.x 中需要至少 5 倍的代码和一些 XML代码).Spring 提供了一个更好的替代方案,它需要更少的 Java 代码(但仍然需要很多 XML 代码).J2EE/EJB2 吸取了 Spring 的教训,并随 Java EE 5 一起提供,它提供了新的 EJB3 API,它比 Spring 更加灵活并且根本不需要 XML.

Noted should be that "Spring" is a quite large framework which not only competes EJB, but also CDI and JPA. Previously, during the dark J2EE ages, when EJB 2.x was extremely terrible to implement (the above EJB 3.x OrderService example would in EJB 2.x require at least 5 times more code and some XML code). Spring offered a much better alternative which required less Java code (but still many XML code). J2EE/EJB2 learned the lessons from Spring and came with Java EE 5 which offers new EJB3 API which is even more slick than Spring and required no XML at all.

Spring 还提供开箱即用的 IoC/DI(控制反转;依赖注​​入).这是在由 XML 配置的 J2EE 时代,这可能非常过分.现在 Spring 也使用注解,但仍然需要一些 XML.从 Java EE 6 开始,在吸取了 Spring 的教训之后,CDI 开箱即用以提供相同的 DI 功能,但不需要任何 XML.使用 Spring DI @Component/@Autowired 和 CDI @Named/@Inject 您可以实现与 JSF 相同的效果使用 @ManagedBean/@ManagedProperty,但是 Spring DI 和 CDI 提供了更多的优势:例如,您可以编写拦截器来预处理或后处理托管 bean创建/销毁或托管bean方法调用,您可以创建自定义范围,生产者和消费者,您可以在范围更广的实例中注入范围更窄的实例等.

Spring also offers IoC/DI (inversion of control; dependency injection) out the box. This was during the J2EE era configured by XML which can go quite overboard. Nowadays Spring also uses annotations, but still some XML is required. Since Java EE 6, after having learned the lessons from Spring, CDI is offered out the box to provide the same DI functionality, but then without any need for XML. With Spring DI @Component/@Autowired and CDI @Named/@Inject you can achieve the same as JSF does with @ManagedBean/@ManagedProperty, but Spring DI and CDI offers many more advantages around it: you can for example write interceptors to pre-process or post-process managed bean creation/destroy or a managed bean method call, you can create custom scopes, producers and consumers, you can inject an instance of narrower scope in an instance of broader scope, etc.

Spring 还提供了本质上与 JSF 竞争的 MVC.将 JSF 与 Spring MVC 混合使用是没有意义的.此外,Spring 还提供了 Data,它本质上是一个在 JPA 之上的额外抽象层,进一步最小化了 DAO 样板(但它本质上并不代表整个业务服务层).

Spring also offers MVC which essentially competes JSF. It makes no sense to mix JSF with Spring MVC. Further Spring also offers Data which is essentially an extra abstraction layer over JPA, further minimizing DAO boilerplate (but which essentially doesn't represent the business service layer as whole).

这篇关于什么时候需要或方便地使用 Spring 或 EJB3 或它们一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆