我对JSF2 + Spring + EJB3的混合使用或它们的任何组合感到有些困惑。我知道Spring的主要特征之一就是依赖注入,但是有了JSF托管的Bean,我可以使用@ManagedBean和@ManagedProperty注释,并且可以获得依赖注入功能。对于EJB3,我更困惑何时与JSF一起使用它,或者甚至有理由使用它。
那么,在哪种情况下使用Spring + JSF2或EJB3 + JSF2是一个好主意?
到现在为止,我仅使用JSF2仅创建了一些小型Web应用程序,而从未使用过Spring或EJB3。但是,我在很多地方看到人们正在一起处理所有这些东西。
首先,Spring和EJB(+ JTA)是竞争技术,通常不能在同一应用程序中一起使用。选择一个或另一个。Spring 或 EJB(+ JTA)。我不会告诉你选择哪个,我只会告诉你一些历史和事实,以便你更轻松地做出决定。
他们试图解决的主要问题是提供具有自动事务管理功能的业务服务层API。想象一下,你需要触发多个SQL查询来执行一个业务任务(例如下订单),而其中一个失败,那么你当然会想一切都回滚了,以便数据库保持相同的状态像以前一样,好像什么也没有发生。如果你不使用事务,那么数据库将处于无效状态,因为第一批查询实际上已经成功。
如果你熟悉基本的JDBC,那么你就应该知道,这可以通过关闭自动提交的连接,然后烧制这些查询的顺序,然后进行实现commit()
以非常相似try的,其catch (SQLException)
一个rollback()
执行。但是,每次实施都非常繁琐。
使用Spring和EJB(+ JTA),默认情况下,单个(无状态)业务服务方法调用透明地计为单个完整事务。这样,你完全不必担心事务管理。你不需要手动创建EntityManagerFactory
,也不需要显式调用em.getTransaction().begin()
,就像将业务服务逻辑紧密耦合到JSF支持bean类和/或在JPA 中使用RESOURCE_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 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一起提供,Java EE 5提供了新的EJB3 API,该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还提供了本质上可以与JSF竞争的MVC。将JSF与Spring MVC混合是没有意义的。此外,Spring还提供了数据,该数据本质上是JPA上的一个额外抽象层,从而进一步减少了DAO样板(但它实际上并不代表整个业务服务层)。
问题内容: 使用弱引用是我从未见过的实现方式,因此,我试图弄清楚它们的用例是什么以及实现将如何工作。你何时需要使用WeakHashMap或WeakReference以及如何使用它? 问题答案: 强引用的一个问题是缓存,尤其是对于非常大的结构(如图像)而言。假设你有一个必须处理用户提供的图像的应用程序,例如我正在使用的网站设计工具。自然地,你想缓存这些图像,因为从磁盘加载它们非常昂贵,并且你希望避免
我主要在工作中处理REST json API。所以我很熟悉它们。但对于我自己的项目,我正在尝试应用引擎,因为我相信它非常适合。 我已经开始用python(使用ferris)编写我的逻辑,在阅读更多关于应用引擎的文章时,我遇到了proorpc和云endpoint。但在我读过的大多数示例中,它们的作用似乎与我在rest api中所做的一样。使用json发出请求,然后得到json响应。或者一个错误。 我
问题内容: 我注意到,如果我对打开的文件进行迭代,则无需“读取”该文件即可更快地对其进行迭代。 即 比 第二个循环将花费大约1.5倍的时间(我在完全相同的文件上使用了timeit,结果是0.442对0.660),并且会得到相同的结果。 所以-我什么时候应该使用.read()或.readlines()? 由于我一直需要遍历正在读取的文件,并且在学习了艰难的方式之后,.read()在大数据上的运行速度
问题内容: 当我尝试按照本指南进行SQLAlchemy Relation Example时:基本关系模式 我有这个代码 它运作良好,但是在指南中,该模型应为: 为什么我不需要或在我的示例中?什么时候应该使用其中一个? 问题答案: 如果使用,则无需在第二个表上声明关系。 如果 不 使用,并分别定义,则如果不使用,则sqlalchemy将不知道如何连接关系,因此修改一个也将修改另一个。 因此,在您的示
问题内容: 为什么要创建抽象或接口类,或者何时应使用抽象或接口类? 问题答案: 仅在声明类必须具有的方法和成员时,才使用接口。实现该接口的任何人都必须声明和实现该接口列出的方法。 如果你还想拥有默认实现,请使用抽象类。扩展抽象类的任何类都必须仅实现其抽象方法和成员,并且将具有抽象类其他方法的一些默认实现,你可以覆盖或不重写。 -编辑-忘了提,Earwicker提醒我 最后,你可以根据需要实现任意数
问题内容: 我在理解类中方法的含义时遇到问题。在下面的代码中,如果我使用该方法,则不使用它也会得到相同的结果。 为什么(或何时)需要使用它? 问题答案: 只创建一个对象 方法由调用