何时有必要或方便使用Spring或EJB3或所有这些工具?
我对JSF2+Spring+EJB3的混合使用或它们的任何组合感到有点困惑。我知道Spring的主要特征之一是依赖项注入,但是对于JSF托管bean,我可以使用何时有必要或方便使用Spring或EJB3或所有这些工具?,spring,jsf,jakarta-ee,ejb,service-layer,Spring,Jsf,Jakarta Ee,Ejb,Service Layer,我对JSF2+Spring+EJB3的混合使用或它们的任何组合感到有点困惑。我知道Spring的主要特征之一是依赖项注入,但是对于JSF托管bean,我可以使用@ManagedBean和@ManagedProperty选项,并且我可以获得依赖项注入功能。对于EJB3,我甚至更困惑于何时将其与JSF一起使用,或者是否有理由使用它 那么,在什么样的情况下使用Spring+JSF2或EJB3+JSF2是一个好主意 到目前为止,我只使用JSF2创建了一些小的web应用程序,而不需要使用Spring或EJ
@ManagedBean
和@ManagedProperty
选项,并且我可以获得依赖项注入功能。对于EJB3,我甚至更困惑于何时将其与JSF一起使用,或者是否有理由使用它
那么,在什么样的情况下使用Spring+JSF2或EJB3+JSF2是一个好主意
到目前为止,我只使用JSF2创建了一些小的web应用程序,而不需要使用Spring或EJB3。然而,我在很多地方看到人们在一起处理所有这些东西。这里没有真正简单的答案,因为春天是很多东西 在一个非常高的层次上,Spring与JavaEE竞争,这意味着您可以使用它们中的任何一个作为完整的堆栈框架 在更细粒度的级别上,SpringIoC容器和SpringBean与JavaEE中CDI和EJB的组合相竞争 至于web层,SpringMVC与JSF竞争。一些SpringXYZTemplate与JPA接口竞争(两者都可以使用例如Hibernate作为这些接口的实现) 可以混合搭配;例如,将CDI和ejbbean与springmvc结合使用,或者将springbean与JSF结合使用
您通常不会同时使用两个直接竞争的技术。SpringBeans+CDI+EJB在同一个应用程序中,或者SpringMVC+JSF是愚蠢的。首先,Spring和EJB(+JTA)是相互竞争的技术,通常不能在同一个应用程序中一起使用。选择一个或另一个。Spring或EJB(+JTA)。我不会告诉你选择哪一个,我只会告诉你一点历史和事实,这样你可以更容易地做出决定
他们试图解决的主要问题是提供具有自动事务管理的业务服务层API。假设您需要启动多个SQL查询来执行单个业务任务(例如下订单),其中一个查询失败,那么您当然希望所有查询都回滚,以便数据库保持与以前相同的状态,就好像什么也没发生一样。如果您没有使用事务,那么数据库将处于无效状态,因为第一批查询实际上成功了 如果您熟悉基本JDBC,那么您应该知道这可以通过关闭连接上的自动提交来实现,然后依次触发这些查询,然后在执行
cry
的catch(SQLException)
中执行rollback()
的同一try
中执行catch(SQLException)
来实现。然而,每次都要实现这一点是相当困难的
使用Spring和EJB(+JTA),单个(无状态)业务服务方法调用在默认情况下透明地计数为单个完整事务。这样,您根本不需要担心事务管理。您不需要手动创建EntityManagerFactory
,也不需要显式调用em.getTransaction().begin()
,就像您将业务服务逻辑紧密耦合到JSF支持bean类和/或在JPA中使用RESOURCE\u LOCAL
而不是JTA
时所做的那样。例如,您可以使用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);
}
}
如果您有一个@EJB私有OrderService OrderService在JSF支持bean中,调用orderService.placeOrder(newOrder)代码>在操作方法中,则将执行单个完整事务。例如,如果一个updateQuantity()
调用或persist()
调用因异常而失败,那么它将回滚迄今为止执行的任何updateQuantity()
调用,并使数据库保持干净整洁的状态。当然,您可以在JSF支持bean中捕获该异常并显示faces消息
应该注意的是,“Spring”是一个相当大的框架,它不仅与EJB竞争,还与CDI和JPA竞争。以前,在黑暗的J2EE时代,EJB2.x的实现非常糟糕(上面的EJB3.xOrderService
示例在EJB2.x中至少需要5倍的代码和一些XML代码)。Spring提供了一个更好的选择,它需要更少的Java代码(但仍然需要很多XML代码)。J2EE/EJB2吸取了Spring的经验教训,并随JavaEE5而来,JavaEE5提供了新的EJB3API,它甚至比Spring更加灵活,并且根本不需要XML
Spring还提供了现成的IoC/DI(控制反转;依赖注入)。这是在J2EE时代,由XML进行配置,这种配置可能非常过火。如今Spring也使用注释,但仍然需要一些XML。从JavaEE6开始,在吸取了Spring的经验教训之后,CDI就提供了现成的功能,以提供相同的DI功能,但不需要任何XML。使用Spring DI@组件
/@自动连线
和CDI@命名
/@注入
可以实现与JSF使用@ManagedBean
/@ManagedProperty
相同的效果,但是SpringDI和CDI提供了更多的优势:例如,您可以编写拦截器来预处理或后处理托管bean创建/销毁或托管bean方法调用,您可以创建自定义作用域、生产者和消费者,您可以在范围更广的实例中插入范围更窄的实例,等等
Spring还提供了MVC,它本质上与JSF竞争。将JSF与SpringMVC混合使用是没有意义的。进一步的Spring还提供了数据,它本质上是JPA之上的一个额外抽象层,进一步最小化了DAO样板(但它本质上并不代表整个业务服务层)
另见:
主要是在您需要透明的DB事务管理和/或遇到问题时