New features in EJB3.1 (Part 3)

 作者:Reza Rahman  文章来源:www.theserverside.com

In the first two articles of this series, I covered a few of the earliest discussed features - optional interfaces for Session beans, Singleton beans, EJB Timer Service enhancements and simplified packaging. In this third article, I'll cover two more features that have been discussed in detail--asynchronous Session Bean invocation and EJB Lite. Remember, none of this has been finalized yet. All of this is really just a peek into the inner workings of the JCP so that you have a chance to provide feedback.

The Early Draft is Out

An early draft of the spec has been released a few weeks ago. You can take a look at the draft yourself at http://jcp.org/aboutJava/communityprocess/edr/jsr318/index.html. As you might already know, the draft covers the entire spec and not just the new features. However, it's not too hard to skip over the parts that are unchanged from EJB 3.0. Keep in mind that changes still being discussed are not yet reflected in the draft. Please also keep in mind that the spec needs to be written for completeness and serves as a contract of sorts for vendor implementations, so it is often difficult if not impossible to focus on readability from a developer's perspective.

Do continue to send in your thoughtful comments on EJB 3.1 to [email protected]. Feel free to CC me at [email protected] too.

Asynchronous Invocation of Session Beans

Asynchronous processing is a surprisingly common requirement for many enterprise applications. Some of the most obvious use cases are triggering fire-and-forget background processes, handling long-running tasks while keeping the user interface receptive or simply increasing application throughput by utilizing the benefits of parallel processing. The easiest way of implementing asynchronous processing in Java EE applications today is using Message Driven Beans. In fact, the first Message Driven Bean example in EJB 3 in Action is used to implement asynchronous order billing. More precisely, a Message Driven Bean ( OrderBillingMDB) asynchronously bills the customer after the order is confirmed and updates the order information with the results of the billing attempt once it is completed. Figure 1 shows this scenario:

Figure 1: Asynchronous order billing

While using Message Driven Beans for asynchronous processing certainly works, it also forces you to deal with messaging and JMS, even for relatively lightweight functionality. This is precisely the problem asynchronous session bean invocation is designed to solve. With this enhancement, you can do asynchronous processing simply by annotating a session bean method with the @Asynchronous annotation. Let's take a look at the re-factored EJB 3 in Action example for asynchronous billing using the feature:

@Stateless public class OrderBillingServiceBean implements OrderBillingService { ... @Asynchronous public void billOrder(Order order) { try { // Attempt to charge the order. bill(order); // Send email notification of billing success. notifyBillingSuccess(order); order.setStatus(OrderStatus.COMPLETE); } catch (BillingException be) { // Send email notification of billing failure. notifyBillingFailure(be, order); order.setStatus(OrderStatus.BILLING_FAILED); } finally { update(order); } } ... }

Because of the @Asynchronous annotation, when the client invokes the OrderBillingService.billOrder method, the call will return immediately instead of blocking until the billOrder method finishes executing. The EJB container will make sure the method gets executed asynchronously (probably using messaging under the hood). As you can see, the return type of the asynchronous method is void. This will probably be the case for a vast majority of asynchronous Session bean methods. However, EJB 3.1 can also support a return type of java.util.concurrent.Future<V>, where V represents the resultant value of an asynchronous invocation. In case you are unfamiliar with it, the Future<V> interface allows you to do things like cancelling an asynchronous invocation, checking if an invocation is complete, check for exceptions and getting the results of an asynchronous invocation. Check out the documentation for the Future<V> interface here: http://java.sun.com/javase/6/docs/api/java/util/concurrent/Future.html. Let's take a quick look at an example using the Future<V> return type. In the billOrder method in the previous example, we set the status of the order according to the outcome of the billing attempt and updated the order. Let's assume that the invoker updates the order themselves and wants to know what the status of the billing attempt was. We could do this by refactoring the billOrder method as follows:

@Stateless public class OrderBillingServiceBean implements OrderBillingService { ... @Asynchronous public Future<OrderStatus> billOrder(Order order) { try { // Attempt to charge the order. bill(order); // Send email notification of billing success. notifyBillingSuccess(order); return new AsyncResult<OrderStatus>(OrderStatus.COMPLETE); } catch (BillingException be) { // Send email notification of billing failure. notifyBillingFailure(be, order); return new AsyncResult<OrderStatus> (OrderStatus.BILLING_FAILED); } } ... }

The javax.ejb.AsyncResult<V> object is a convenience implementation of the Future<V> interface. It takes the result of the asynchronous invocation as a constructor argument. There's nothing stopping you from using your own implementation of Future<V> however. Asynchronous invocation supports a few other neat features like delivery guarantees and transacted send semantics. For details, check out the spec draft.

What do you think of the asynchronous Session bean invocation feature? I personally think it's pretty cool. Can you think of any other features that could be added?

EJB Lite is Here

One of the major complaints many people have had of EJB and Java EE in general is that it is a kitchen sink solution that tries to be everything to everyone at the same time. Although it's important to appreciate the fact that Java EE is a standard and must aim to be comprehensive, this criticism is justified. Java EE 6 Profiles are a reflection of this fact. Roberto Chinnici, the co-spec lead for the Java EE 6 spec has blogged about Java EE 6 Profiles here: http://weblogs.java.net/blog/robc/archive/2008/02/profiles_in_the_1.html. In short, Profiles define subsets of Java EE suited to a particular purpose. For example, the minimal Web Profile is geared towards very simple web applications.

Focusing on EJB in particular, the typical web project is probably very unlikely to use remoting, the EJB Timer service or Message Driven beans. In fact, a vast majority of EJB applications probably simply utilize injection, persistence management, stateless session beans and declarative transactions. EJB Lite is an attempt to follow this observation and pare down EJB features as much as possible. On one hand, this allows for very simple, lightweight implementations. On the other hand, this means learning EJB Lite could consist of leaning just a small handful of annotations and almost no configuration. The next generation of lightweight Java EE application servers will probably implement EJB Lite instead of the entire EJB 3.1 specification. For example, a very tantalizing possibility this opens up is creating an implementation of EJB Lite on top of Spring going a step further down the lines of the Pitchfork project.

The following is the current list of features proposed for EJB Lite:

  • Stateless, Stateful, and Singleton session beans
  • Only local EJB interfaces or no interfaces
  • No support for asynchronous invocation (should this be included?)
  • Interceptors
  • Declarative security
  • Declarative and programmatic transactions

What are your thoughts on this list? Should it be pared down further? Should it be expanded? What do you think is important for your application? For reference, here is a table comparing major EJB and EJB Lite features:

Feature

EJB Lite

EJB

Stateless beans

Stateful beans

Singleton beans

Message driven beans

 

No interfaces

Local interfaces

Remote interfaces

 

Web service interfaces

 

Asynchronous invocation

 

Interceptors

Declarative security

Declarative transactions

Programmatic transactions

Timer service

 

EJB 2.x support

 

CORBA interoperability

 

Table 1: EJB and EJB Lite Feature Comparison

Features Still on the Table

In this series so far, I've covered Singleton beans, optional interfaces for Session beans, Timer service features, simplified EJB packaging, Session bean asynchronous invocation and EJB Lite. There are still a number of features that are being discussed by the group and are in various stages of incompleteness:

  1. Support for stateful web services via Stateful Session Bean web service endpoints.
  2. The standardization of JNDI mapping instead of keeping it for vendors to decide.
  3. Support for using EJB 3.1 in Java SE environments. This is primarily geared towards unit testing.

What are your thoughts on these features? If you think they are important, voice your opinion by emailing the expert group. Are there any other features you would like to see? As the state of these features become clearer, I'll write about them in this series. As many folks have requested, I'll also cover EJB and WebBeans integration as well as some of the enhanced DI features offered by WebBeans. Until then, adios amigos!

References

  1. JSR 316: Java EE 6, http://jcp.org/en/jsr/detail?id=316.
  2. JSR 318: Enterprise JavaBeans 3.1, http://jcp.org/en/jsr/detail?id=318.
  3. JSR 299: Web Beans, http://jcp.org/en/jsr/detail?id=299.
  4. Spring Pitchfork Project, http://static.interface21.com/projects/pitchfork/files/m4/docs/reference/html_single/.

你可能感兴趣的:(New features in EJB3.1 (Part 3))