42

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

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

到目前为止,我只使用 JSF2 创建了一些小型 Web 应用程序,并且从未需要使用 Spring 或 EJB3。然而,我在很多地方看到人们一起处理所有这些东西。

4

2 回答 2

72

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


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

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

使用 Spring 和 EJB(+JTA),单个(无状态)业务服务方法调用默认透明地计为单个完整事务。这样,您根本不需要担心事务管理。当您将业务服务逻辑紧密耦合到 JSF 支持 bean 类和/或在 JPA中使用而不是使用时,您不需要手动创建EntityManagerFactory,也不需要显式调用和。例如,您可能只有以下使用 JPA 的 EJB 类:em.getTransaction().begin()RESOURCE_LOCALJTA

@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);
    }

}

如果您@EJB private OrderService orderService;的 JSF 支持 bean 中有一个并调用orderService.placeOrder(newOrder);action 方法中的 ,那么将执行一个完整的事务。例如,如果其中一个updateQuantity()调用或persist()调用因异常而失败,那么它将回滚迄今为止执行的所有updateQuantity()调用,并使数据库保持干净和清晰的状态。当然,您可以在 JSF 支持 bean 中捕获该异常并显示一条面孔消息左右。

需要注意的是,“Spring”是一个相当大的框架,它不仅与 EJB 竞争,还与 CDI 和 JPA 竞争。以前,在黑暗的 J2EE 时代,当 EJB 2.x 难以实现时(上面的 EJB 3.xOrderService示例在 EJB 2.x 中需要至少 5 倍以上的代码和一些 XML 代码)。Spring 提供了一个更好的替代方案,它需要更少的 Java 代码(但仍然需要很多 XML 代码)。J2EE/EJB2 从 Spring 中吸取了教训,并附带了 Java EE 5,它提供了新的 EJB3 API,它比 Spring 更流畅,根本不需要 XML。

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

也可以看看:

于 2013-08-22T11:33:07.090 回答
5

这里没有真正简单的答案,因为 Spring 有很多东西。

在非常高的层面上,Spring 与 Java EE 竞争,这意味着您可以将其中任何一个用作完整的堆栈框架。

在更细粒度的级别上,Spring IoC 容器和 Spring Beans 与 Java EE 中的 CDI 和 EJB 组合竞争。

至于 web 层,Spring MVC 与 JSF 竞争。一些 Spring xyzTemplate 与 JPA 接口竞争(两者都可以使用 Hibernate 作为这些接口的实现)。

可以混合搭配;例如,将 CDI 和 EJB bean 与 Spring MVC 一起使用,或者将 Spring Beans 与 JSF 一起使用。

您通常不会同时使用 2 个直接竞争的技术。Spring beans + CDI + EJB 在同一个应用程序中,或者 Spring MVC + JSF 是愚蠢的。

于 2013-08-22T08:51:17.910 回答