何时需要或方便地将Spring或EJB3或它们全部一起使用?

use*_*726 39 jsf spring ejb java-ee service-layer

混淆使用JSF2 + Spring + EJB3或它们的任意组合让我感到有些困惑.我知道Spring的一个主要特性是依赖注入,但是我可以使用JSF托管bean @ManagedBean@ManagedPropertyanotations,并获得依赖注入功能.使用EJB3,我更加困惑何时将其与JSF一起使用,或者甚至有理由使用它.

那么,在什么样的情况下使用Spring + JSF2或EJB3 + JSF2是个好主意?

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

Bal*_*usC 66

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


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

如果您熟悉基本的JDBC,那么您应该知道这可以通过关闭连接上的自动提交,然后按顺序触发这些查询,然后执行与其执行的a commit()相同的查询来实现.然而,每次实施都非常繁琐.trycatch (SQLException)rollback()

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

}
Run Code Online (Sandbox Code Playgroud)

如果您@EJB private OrderService orderService;在JSF支持bean中有一个并orderService.placeOrder(newOrder);在action方法中调用,那么将执行单个完整事务.例如,如果其中一个updateQuantity()调用或persist()调用因异常而失败,那么它将回滚任何到目前为止执行的updateQuantity()调用,并使数据库处于干净和清晰的状态.当然,您可以在JSF辅助bean中捕获该异常并显示faces消息.

值得注意的是,"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.

Spring还提供IoC/DI(控制反转;依赖注入).这是在由XML配置的J2EE时代,这可能会非常落伍.如今Spring也使用注释,但仍然需要一些XML.从Java EE 6开始,在学习了Spring的经验之后,CDI就提供了相同的DI功能,但是不需要XML.借助于Spring DI @Component/ @Autowired和CDI @Named/ @Inject你可以达到同样的JSF确实与@ManagedBean/ @ManagedProperty,但春天DI和CDI提供围绕它更多的优点:比如,你可以写拦截预先处理或后处理管理bean创建/销毁或在托管bean方法调用中,您可以创建自定义范围,生产者和使用者,您可以在更广范围的实例中注入更窄范围的实例,等等.

Spring还提供MVC,它基本上与JSF竞争.将JSF与Spring MVC混合是没有意义的.此外,Spring还提供了数据,这实际上是JPA上的额外抽象层,进一步最小化了DAO样板(但实质上并不代表业务服务层).

也可以看看:


Mik*_*aun 5

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

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

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

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

可以混合搭配;例如,在Spring MVC中使用CDI和EJB bean,或者在JSF中使用Spring Beans。

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