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

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

评论

主要是,当您需要透明的DB事务管理和/或厌倦了所有JDBC样板代码时。请注意,Spring和EJB竞争激烈,通常不会混合在一起。选择一个或另一个。相关:stackoverflow.com/questions/13011392/jsf-service-layer

感谢您的回答,在我的项目中,我使用开放式JPA进行数据库事务管理,使用jpa或EJB有什么区别?

EJB是JavaEE的一部分,JavaEE是由某些应用服务器(如JBoss或GlassFish)提供的容器。该服务器本身包含一个JPA实现,作为JavaEE容器。您还可以在Spring中配置JPA配置,在这种情况下,您可以自己提供实现(可以是EclipseLink,Hibernate ..)

像JDBC一样,JPA根本没有自动事务管理。您仍然需要自行管理(t = em.getTransaction(),t.begin(),t.commit()等)。 JPA不是事务管理API,而是ORM API。

#1 楼

首先,Spring和EJB(+ JTA)是竞争技术,通常不能在同一应用程序中一起使用。选择一个或另一个。 Spring或EJB(+ JTA)。我不会告诉您选择哪个,我只会告诉您一些历史和事实,以便您可以更轻松地做出决定。

他们要解决的主要问题是提供一个具有自动交易管理功能的业务服务层API。想象一下,您需要触发多个SQL查询来执行一个业务任务(例如下订单),而其中一个失败,那么您当然希望一切都回滚,以便数据库保持相同的状态像以前一样,好像完全没有任何反应。如果您不使用事务,那么数据库将处于无效状态,因为第一批查询实际上已经成功。
如果您熟悉基本的JDBC,那么您应该知道这可以通过关闭连接上的自动提交,然后依次触发这些查询,然后在与执行commit()相同的try中执行catch (SQLException),可以实现此目的。但是,每次实现起来都非常繁琐。
对于Spring和EJB(+ JTA),默认情况下,单个(无状态)业务服务方法调用透明地计为单个完整事务。这样,您完全不必担心事务管理。您无需手动创建rollback(),也无需显式调用EntityManagerFactory,例如在将业务服务逻辑紧密耦合到JSF支持bean类和/或在JPA中使用em.getTransaction().begin()而不是RESOURCE_LOCAL时,您将不需要这样做。例如,您可以利用JPA拥有以下EJB类:
@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中有一个JTA,并在action方法中调用了@EJB private OrderService orderService;,那么将执行一个完整的事务。例如,如果orderService.placeOrder(newOrder);调用或updateQuantity()调用之一失败并发生异常,则它将回滚迄今执行的所有persist()调用,并使数据库保持干净整洁的状态。当然,您可以在JSF支持bean中捕获该异常并显示一个faces消息左右。以前,在黑暗的J2EE时代,EJB 2.x的实现极其糟糕(上述EJB 3.x updateQuantity()示例在EJB 2.x中将需要至少5倍的代码和一些XML代码)。 Spring提供了一个更好的替代方案,它需要更少的Java代码(但仍然需要许多XML代码)。 J2EE / EJB2借鉴了Spring的经验,并提供了Java EE 5,该Java EE 5提供了新的EJB3 API,它比Spring更加精巧并且完全不需要XML。 )。这是在XML所配置的J2EE时代中,这可能太过分了。如今,Spring还使用注释,但是仍然需要一些XML。从Java EE 6开始,从Spring汲取了教训之后,CDI便立即提供了相同的DI功能,但是不需要任何XML。使用Spring DI OrderService / @Component和CDI @Autowired / @Named可以实现与JSF @Inject / @ManagedBean相同的功能,但是Spring DI和CDI围绕它提供了更多优势:例如,您可以将拦截器写入预处理或后处理托管Bean创建/销毁或托管Bean方法调用,您可以创建自定义范围,生产者和使用者,还可以在范围更广的实例中注入范围更窄的实例,等等。
Spring还提供了与JSF竞争的MVC。将JSF与Spring MVC混合是没有意义的。此外,Spring还提供了数据,该数据本质上是JPA上的一个额外抽象层,从而进一步减少了DAO样板(但它基本上不代表整个业务服务层)。
另请参见:

Java EE到底是什么?
JSF控制器,服务和DAO
@Stateless bean与@Stateful bean


评论


谢谢!这就是我一直在寻找的答案。.我对所有这些技术及其目的有些困惑。

–user2018726
13年8月23日在13:15

#2 楼

因为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 Bean与JSF一起使用。在同一应用程序中使用Spring bean + CDI + EJB,或者Spring MVC + JSF很愚蠢。