技术开发 频道

了解 Java EE 5

  EJB 3.0 规范的更新包括以下内容:

  容器服务

  回调

  拦截器

  依赖项注入

  容器服务

  EJB 组件由于隐式支持事务管理和安全性,因此非常受欢迎。EJB 3.0 规范使用标注(和 XML)来应用容器服务。下面给出了一个示例,介绍如何在无状态会话 Bean 上指定事务属性。

  清单 6

1 @Stateless public class StockBean
2
3   {
4
5   @TransactionAttribute(TransactionAttributeType.REQUIRESNEW)
6
7   public double getQuote(String symbol)
8
9   {
10
11   return 100.33;
12
13   }
14
15   }
16
17

  此标注意味着,该方法将在新事务中运行。请参见规范,了解不同标注的具体语法和语义,但相同事务和安全功能都有标注。还可以使用 XML 部署描述符应用容器服务,而XML 部署描述符可以在部署时覆盖启用灵活性的标注。

回调是什么情况?在 EJB 3.0 之前,必须在 Bean 类上实现回调方法,如 ejbCreate();Bean 类必须实现所有方法,无论是否使用它们。在大多数情况下,这些方法实现是空的。现在还通过标注并使用回调方法或回调侦听器类处理回调。下面是一个示例,说明如何编写代码来使用回调方法响应回调:

  清单 7

1 @Stateless public class StockBean implements Stock
2
3   public double getQuote(String symbol)
4
5   {
6
7   return 100.33;
8
9   }
10
11   @PostConstruct initializeCache()
12
13   {
14
15   }
16
17   }
18
19

  以上代码可让您在创建 Bean 实例之后实现代码。如果希望使用回调侦听器,则可以创建回调侦听器类:

  清单 8

1 public class MyCallbackListener
2
3   {
4
5   @PrePassivate public clearCache(Object obj)
6
7   {
8
9   Stock stock = (Stock) obj;
10
11   //perform logic
12
13   }
14
15   }
16
17

  不属于 Bean 类的回调类必须获取 java.lang.Object 参数。容器然后传递 Bean 实例。Bean 类通过使用特殊回调标注在 Bean 类级别添加回调侦听器类:

  清单 9

1 @CallbackListener MyCallbackListener
2
3   @Stateless public class StockBean implements Stock
4
5   public double getQuote(String symbol)
6
7   {
8
9   return 100.33;
10
11   }
12
13   }
14
15

  回调方法比较好,因为在代码中包括回调方法是有条件的,这与实现接口不同。

  拦截器

  EJB 规范另一增强功能是使用拦截器。EJB 组件以前缺少的功能是无法对预处理/后处理和横切关注点(与 Servlet 筛选器对 Servlet 的作用类似)等内容执行面向方面的开发 (AOP)。现在可以开发一个拦截器类并将其应用到 Bean。下面是一个审核 StockBean 类调用的拦截器类的示例:

  清单 10

1 public class StockRequestAudit {
2
3   @AroundInvoke
4
5   public Object auditStockOperation(InvocationContext inv) throws
6
7   Exception {
8
9   try {
10
11   Object result = inv.proceed();
12
13   Auditor.audit(inv.getMethod().getName(), inv.getParameters[0]);
14
15   return result;
16
17   } catch (Exception ex) {
18
19   Auditor.auditFailure(ex);
20
21   throw ex;
22
23   }
24
25   }
26
27   }
28
29

  上面的拦截器拦截对目标 EJB 方法的调用,然后调用 InvocationContext 上的 proceed() 方法。这可让该调用方法流经实际被调用的 EJB 方法。在返回目标 EJB 方法之后,它使用 InvocationTarget 中的元数据来获取被调用的目标 EJB 组件的方法名和参数。然后可以将拦截器应用到 Bean 类:

  清单 11

1 @Stateless @Interceptors({StockRequestAudit})
2
3   public class StockBean implements Stock
4
5   public double getQuote(String symbol)
6
7   {
8
9   return 100.33;
10
11   }
12
13   }
14
15

  另外,还可以开发一个在 Bean 类内部实现的拦截器方法,而且可以指定多个拦截器,在指定多个拦截器时,它们的调用顺序由其在 Bean 类中定义的顺序指定。还可以使用 XML 在 Bean 以外应用拦截器,这在 AOP 中为首选方法,因为您希望向 Bean 透明地应用横切关注点。

  依赖项注入

  依赖于数据源之类的 EJB 代码依赖项和 EJB 客户端调用 EJB 组件的方式难以进行 EJB 开发测试。为解决此问题,EJB 3.0 规范引入了依赖项注入机制。EJB 没有使用 JNDI 查找,而是通过注入代码定义一个资源引用。下面是 EJB Bean 的一个示例,此 EJB Bean 需要调用另一个 EJB 组件并使用数据源执行 JDBC 工作:

  清单 12

1 @Stateless public class StockBean implements Stock
2
3   {
4
5   @EJB(name="MarketBean", businessInterface="Market")
6
7   Market market;
8
9   @Resource(name="StockDB, resourceType="javax.sql.DataSource")
10
11   DataSource stockDS
12
13   public double getQuote(String symbol)
14
15   {
16
17   Connection con = stockDS.getConnection();
18
19   //DO JDBC work
20
21   return market.getCurrentPrice(symbol);
22
23   }
24
25   }
26
27

  依赖项注入可以通过多种方式进行,例如通过 setter 方法或类变量。有关详细信息,请参见规范。

  Java 持久性体系结构 (JPA)

  EJB 持久性的规范已发生了显著变化。该规范称为容器管理的持久性 (CMP),它没有定义映射层,而是由容器映射;因此它由供应商实现映射。受多个商业和开源产品和技术(如 Hibernate、Java Data Objects (JDO) 和 TopLink)的影响,EJB 3.0 引入了新的持久性样式,即基于 POJO 的持久性:

  在成功模式上建模。

  简化 JDBC 访问模式。

  可以与 Web 服务集成。

  不受容器的阻碍;可以在 Java EE 或 Java SE 环境中使用 JPA。

  标准化 O/R 映射元数据。

  支持自顶向下、中间相遇和自底向上的开发。

  支持断接和连接的对象状态,省去了对单独的数据传输对象的需要。图 2 显示了一个示例。

  图 2. 支持对象状态

  

0
相关文章