什么时候使用Spring或EJB3或它们全部必要或方便? [英] When is it necessary or convenient to use Spring or EJB3 or all of them together?

查看:159
本文介绍了什么时候使用Spring或EJB3或它们全部必要或方便?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有点混淆使用JSF2 + Spring + EJB3或者这些的任何组合。我知道Spring的主要特征之一是依赖注入,但是使用JSF托管bean,我可以使用 @ManagedBean @ManagedProperty anotations和我获得依赖注入功能。使用EJB3,我更加困惑于何时与JSF一起使用它,或者甚至有理由使用它。



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



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

解决方案

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






他们试图解决的主要问题是提供一个具有自动事务管理的业务服务层API。想象一下,您需要启动多个SQL查询以执行单个业务任务(例如,下订单),其中一个失败,那么您当然会将所有回滚到所有数据库保持与之前相同的状态,好像完全没有发生。如果您没有使用交易,则数据库将处于无效状态,因为第一批查询实际上已成功。



如果您熟悉使用基本的JDBC,那么你应该知道这可以通过关闭连接上的自动提交来实现,然后按顺序触发这些查询,然后执行 commit() 尝试 catch(SQLException) a 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);
}

}

如果你有一个 @EJB private OrderService orderService; 在您的JSF支持bean中,并在操作方法中调用 orderService.placeOrder(newOrder); 将执行单个完整交易。如果例如 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 ,但是Spring DI和CDI提供了更多的优势:您可以通过如下方式来编写拦截器来预处理或后处理托管bean创建/销毁或受管Bean方法调用,您可以创建自定义范围,生产者和消费者,您可以在更广泛的范围等内注入较窄范围的实例。



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



另请参见:




I'm a little confused by the mixed use of JSF2+Spring+EJB3 or any combination of those. I know one of the Spring principal characteristics is dependency injection, but with JSF managed beans I can use @ManagedBean and @ManagedProperty anotations and I get dependency injection functionality. With EJB3 I'm even more confused about when to use it along with JSF or if there is even a reason to use it.

So, in what kind of situation would it be a good idea to use Spring+JSF2 or EJB3+JSF2?

Until now I have created just some small web applications using only JSF2 and never needed to use Spring or EJB3. However, I'm seeing in a lot of places that people are working with all this stuff together.

解决方案

First of all, Spring and EJB(+JTA) are competing technologies and usually not to be used together in the same application. Choose the one or the other. Spring or EJB(+JTA). I won't tell you which to choose, I will only tell you a bit of history and the facts so that you can easier make the decision.


Main problem they're trying to solve is providing a business service layer API with automatic transaction management. Imagine that you need to fire multiple SQL queries to perform a single business task (e.g. placing an order), and one of them failed, then you would of course like that everything is rolled back, so that the DB is kept in the same state as it was before, as if completely nothing happened. If you didn't make use of transactions, then the DB would be left in an invalid state because the first bunch of the queries actually succeeded.

If you're familiar with basic JDBC, then you should know that this can be achieved by turning off autocommit on the connection, then firing those queries in sequence, then performing commit() in the very same try in whose catch (SQLException) a rollback() is performed. This is however quite tedious to implement everytime.

With Spring and EJB(+JTA), a single (stateless) business service method call counts by default transparently as a single full transaction. This way you don't need to worry about transaction management at all. You do not need to manually create EntityManagerFactory, nor explicitly call em.getTransaction().begin() and such as you would do when you're tight-coupling business service logic into a JSF backing bean class and/or are using RESOURCE_LOCAL instead of JTA in JPA. You could for example have just the following EJB class utilizing JPA:

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

}

If you have a @EJB private OrderService orderService; in your JSF backing bean and invoke the orderService.placeOrder(newOrder); in the action method, then a single full transaction will be performed. If for example one of the updateQuantity() calls or the persist() call failed with an exception, then it will rollback any so far executed updateQuantity() calls, and leave the DB in a clean and crisp state. Of course, you could catch that exception in your JSF backing bean and display a faces message or so.

Noted should be that "Spring" is a quite large framework which not only competes EJB, but also CDI and JPA. Previously, during the dark J2EE ages, when EJB 2.x was extremely terrible to implement (the above EJB 3.x OrderService example would in EJB 2.x require at least 5 times more code and some XML code). Spring offered a much better alternative which required less Java code (but still many XML code). J2EE/EJB2 learned the lessons from Spring and came with Java EE 5 which offers new EJB3 API which is even more slick than Spring and required no XML at all.

Spring also offers IoC/DI (inversion of control; dependency injection) out the box. This was during the J2EE era configured by XML which can go quite overboard. Nowadays Spring also uses annotations, but still some XML is required. Since Java EE 6, after having learned the lessons from Spring, CDI is offered out the box to provide the same DI functionality, but then without any need for XML. With Spring DI @Component/@Autowired and CDI @Named/@Inject you can achieve the same as JSF does with @ManagedBean/@ManagedProperty, but Spring DI and CDI offers many more advantages around it: you can for example write interceptors to pre-process or post-process managed bean creation/destroy or a managed bean method call, you can create custom scopes, producers and consumers, you can inject an instance of narrower scope in an instance of broader scope, etc.

Spring also offers MVC which essentially competes JSF. It makes no sense to mix JSF with Spring MVC. Further Spring also offers Data which is essentially an extra abstraction layer over JPA, further minimizing DAO boilerplate (but which essentially doesn't represent the business service layer as whole).

See also:

这篇关于什么时候使用Spring或EJB3或它们全部必要或方便?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆