stackoverflow上的一个问题:

主要为了区分 @ManagedBean @Named 

好几个包下都有,比较容易混淆。

参考:https://stackoverflow.com/questions/11986847/java-ee-6-javax-annotation-managedbean-vs-javax-inject-named-vs-javax-faces 

翻译:http://www.andygibson.net/blog/article/comparing-jsf-beans-cdi-beans-and-ejbs/

 

Java EE 6中提供的托管bean的差异类型仍然存在很多混淆,其中EJB,CDI bean和JSF托管bean都可用。本文旨在澄清它们之间的一些差异,并定义何时使用它们。

许多人认为所有这些不同类型的豆子都有一些含义,他们只是不明白。然而,问题在于不同的API重叠,这是不幸的。

JSF托管Bean,CDI Bean和EJB

JSF最初是使用自己的托管bean和依赖注入机制开发的,该机制针对JSF 2.0进行了增强,以包含基于注释的bean。当CDI与Jav​​a EE 6一起发布时,它被认为是该平台的托管bean框架,当然,EJB已经过时了十多年。

问题当然是知道使用哪一个以及何时使用,但它们都涉及相同的过程。通常,必须将类标识为托管bean,并且在必要时,如果要在JSF中使用,则需要范围,限定符和名称。以下是不同类型的托管bean以及如何以及何时使用它们的简要说明。

让我们从最简单的JSF Managed bean开始。

JSF Managed Beans

简而言之,如果您正在为Java EE 6开发并使用CDI,请不要使用它们。它们为依赖注入提供了一种简单的机制,并为网页定义了支持bean,但它们远没有CDI bean强大。

可以使用带有可选参数的@ javax.faces.bean.ManagedBean批注来定义它们name。此名称可用于从JSF页面引用bean。

可以使用javax.faces.bean包中定义的不同作用域之一将作用域应用于bean,其中包括请求,会话,应用程序,视图和自定义作用域。

1

2

3

4

6

@ManagedBean(name="someBean")

@RequestScoped

public class SomeBean {

    ....

    ....

}

如果没有某种手动编码,JSF bean不能与其他类型的bean混合使用。

CDI bean

CDI是作为Java EE 6的一部分发布的bean管理和依赖注入框架,它包含一个完整,全面的托管bean工具。CDI bean比简单的JSF托管bean更先进,更灵活。他们可以使用拦截器,会话范围,事件,类型安全注入,装饰器,构造型和生产者方法。

要部署CDI bean,必须beans.xml在类路径中放置一个名为META-INF文件夹的文件。一旦你这样做,那么包中的每个bean都变成了一个CDI bean。CDI中有很多功能,这里有很多功能,但作为类似JSF功能的快速参考,您可以使用javax.enterprise.context包中定义的一个范围来定义CDI bean的范围(即请求,会话,会话和应用范围)。如果要从JSF页面使用CDI bean,可以使用javax.inject.Named批注为其命名。要将bean注入另一个bean,可以使用javax.inject.Inject批注对该字段进行批注。

1

2

3

4

6

7

@Named("someBean")

@RequestScoped

public class SomeBean {

 

    @Inject

    private SomeService someService;

}

可以通过使用有助于匹配您想要注入的特定类的限定符来控制上面定义的自动注入。如果您有多种付款类型,则可以添加限定符,以确定它是否是异步的。虽然您可以将@Named注释用作限定符,但您不应该像在EL中公开bean那样提供它。

CDI通过使用代理来处理具有不匹配范围的bean的注入。因此,您可以将请求范围的bean注入到会话范围的bean中,并且该引用在每个请求上仍然有效,因为对于每个请求,代理重新连接到请求范围bean的实时实例。

CDI还支持拦截器,事件,新的会话范围和许多其他功能,使其成为比JSF托管bean更好的选择。

EJB

EJB早于CDI bean,并且在某种程度上类似于CDI bean,并且在其他方​​面非常不同。首先,CDI bean和EJB之间的区别在于EJB是:

  • 交易
  • 远程或本地
  • 能够钝化有状态的bean释放资源
  • 能够利用计时器
  • 可以是异步的

这两种类型的EJB称为无状态和有状态。无状态EJB可以被认为是线程安全的一次性bean,它不会在两个Web请求之间维护任何状态。有状态EJB确实保持状态,只要需要它们就可以创建和保持状态,直到它们被丢弃为止。

定义EJB很简单,只需在类中添加javax.ejb.Statelessjavax.ejb.Stateful注释即可。

1

2

3

4

6

7

8

@Stateless

public class BookingService {

 

  public String makeReservation(Item Item,Customer customer) {

    ...

    ...

  }

}

无状态bean必须具有依赖范围,而有状态会话bean可以具有任何范围。默认情况下,它们是事务性的,但您可以使用事务属性注释。

虽然EJB和CDI bean在功能方面非常不同,但编写代码以集成它们非常相似,因为CDI bean可以注入EJB,而EJB可以注入到CDI bean中。将一个注入另一个时无需进行任何区分。同样,CDI通过使用代理来处理不同的范围。一个例外是CDI不支持注入远程EJB,但可以通过为它编写一个简单的生成器方法来实现。

所述javax.inject.Named注释以及任何限定符可在一个EJB被用于匹配到注入点。

何时使用哪个bean

你怎么知道何时使用哪种豆子?简单。

永远不要使用JSF托管bean,除非您在servlet容器中工作并且不想尝试让CDI在Tomcat中工作(尽管我有一个Maven原型,因此没有任何借口)。

通常,您应该使用CDI bean,除非您需要EJB中可用的高级功能,例如事务功能。您可以编写自己的拦截器来使CDI bean成为事务性的,但是现在,它更容易使用EJB,直到CDI获得即将到来的事务性CDI bean。如果你被困在一个servlet容器中并且正在使用CDI,那么手写事务或你自己的事务拦截器是没有EJB的唯一选择。

 

 

 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐