`
hereson2
  • 浏览: 458363 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

New Features in EJB3.1

阅读更多
作者 Reza Rahman 摘自http://www.theserverside.com
This series of articles is a preview of the changes the EJB 3.1 expert group is working on for the next version of the Java EE specification. The idea is to give you a head's up on the changes as well as gather your feedback early so the expert group has the best chance of getting it right. EJB 3.0 brought simplicity to Java EE 5 by moving away from a heavyweight programming model. EJB 3.1 aims to build on those successes by moving further down the path of simplicity as well as adding a handful of much-needed features. In each article in this series, I will let you know about the progress made by the expert group over the next few months.
In this first article, I'll cover the two features that have been discussed in detail so far--making interfaces optional for EJBs and Singleton Beans. I'll also give you a look-ahead into the possible features yet to be discussed. 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 provide early feedback.

EJB Interfaces are Optional

The very first change the expert group covered was removing the last remaining obstacle to making EJBs look just like POJOs in their simplest form by making Session Bean business interfaces optional.

Interface-based programming is clearly a useful technique in writing loosely-coupled, unit-testable applications. That is precisely why both EJB 2.1 and Spring promote the idea of component interfaces. In fact, at least one interface is required even for EJB 3.0 Session Beans (this is not a requirement for EJB 3.0 Message Driven Beans).

The trouble is that component interfaces are just a needless abstraction in a lot of circumstances. I can't remember the times I silently cursed under my breath as I carried out the mechanical task of writing interfaces just because the framework needed it or the architect sitting in some ivory tower mandated it. A lot of times, just a regular Java object is really all you need for your foreseeable needs, especially if you don't really do much unit testing and loose-coupling is just not enough of a concern for the application.

EJB 3.1 allows you to do just that. Now you do not need any interfaces for Session Beans, just like JPA Entities and Message Driven Beans. All you have to do is annotate a POJO with the @Stateless or @Stateful to get a fully functional EJB. Take a look at the example below modified from the Session Bean chapter in EJB 3 in Action:

@Stateless public class PlaceBidBean ...{
@PersistenceContext
    
private EntityManager entityManager;
    
public void placeBid (Bid bid) ...{
    entityManager.persist(bid);
    }

}
To keep things interesting, let's add a few more features to this bargain-basement bean:
@Stateless @WebService
public class PlaceBidBean ...{
    @PersistenceContext
  
private EntityManager entityManager;
  @WebMethod 
public void placeBid (Bid bid) ...{
  entityManager.persist(bid);
  }

}

In the above example, we are using JAX-WS 2.0 to expose the simple little placeBid method as a web service. We're also using JPA to persist a Bid entity. PlaceBidBean has the full range of Stateless Session Bean functionality available behind-the-scenes including pooling, thread-safety, component life-cycle, interceptors, security and declarative transactions. For example, as you might have guessed if you are familiar with EJB 3.0, the placeBid method is wrapped in a container-managed JTA transaction by default. RMI-based remoting will also be supported for these beans, although the exact semantics hasn't been solidified yet.

Besides making it easy to get going with simple bean classes, dropping the interface requirements also makes using EJB 3.1 beans in WebBeans easy. Gavin King is leading the WebBeans JSR (JSR 299), largely inspired by the lessons in JBoss Seam. WebBeans is expected to make JSF, JPA and EJB 3.1 virtually seamless (no pun intended) and make Java EE 6 truly feel like a fully integrated stack.

The Singleton Beans are Here

EJB 3.1 Singleton Beans are the middleware equivalent of the GOF Singleton pattern. In the Java EE context, they are primarily used to store application-wide shared data.
Think about all the times you needed to cache some data in memory so you didn't have to do the same old database lookups over and over again from different parts of the application. Neither Stateless Session Beans nor Stateful Session Beans meet this need. While Stateful Session Beans can maintain a session cache, it can't really be shared amongst the application tier components very easily.

There are various ways of solving this problem now. The simplest way is to use static fields or GOF Singleton pattern POJOs. More complex strategies that can work across an application cluster include using the Servlet container's application scope, JBoss Cache, OSCache, JCS and SwarmCache. Commercial solutions include Tangosol Coherence and Terracotta. While these solutions do work a majority of the time, they have a lot of weaknesses. Some are not thread-safe out of the box (static fields, Singleton POJOs), some are not transactional (Singleton POJOs, the Servlet application scope, OSCache, JCS, SwarmCache), none are remoteable and none have any security mechanisms. Other than the simplest solutions, all of them require the use of non-standard, third-party code. Enter EJB 3.1 Singletons.

The container is guaranteed to maintain a single shared instance of an EJB 3.1 Singleton. This means that Singletons can cache state across the application tier. Because it is an EJB, Singletons have all the middleware services you might expect--declarative transaction management, security, remoting, concurrency management, dependency injection, component life-cycle callbacks, interceptors and so on. Like all other EJBs, Singletons are simply annotated POJOs. Here is a simple example:

@Singleton
public class DiscountRateBean ...{
    @PersistenceContext
    
private EntityManager entityManager;
    
private Rate rate;
    @PostConstruct
    
private void init() ...{
    rate 
= entityManager.find(Rate.class1);
    }

    @PreDestroy
    
private void destroy() ...{
    entityManager.merge(rate);
    }

    
public void setRate(Rate rate) ...{
    
this.rate = rate;
    }

    
public Rate getRate() ...{
    
return rate;
    }

}

The example is using JPA and bean life-cycle callbacks to load data on startup and save the data when the bean is destroyed (usually when the application is being shut-down). Any bean calling getRate and setRate is guaranteed access to the shared data stored in a single instance of DiscountRateBean. You'll notice an interesting problem--any updates will be lost if the container does not get a chance to call the pre-destroy callback. We'll see how to minimize this problem using cron-like timers in a future article.

By default, all Singleton methods are made thread-safe and transactional. This means that all multithreaded access to the bean is serialized and all methods are assumed to have a REQUIRED transaction attribute (do you think that these are sensible defaults? If not, why?). You can change transactional behavior using the @TransactionManagement and @TransactionAttribute annotations just like you would do for a Stateful or Stateless Session Bean. If you've ever done this sort of thing for a relatively large scale application, you know having both the getRate and setRate methods serialized can be a serious performance bottleneck. In reality, you simply need a read-lock on the getRate method while a read-write lock should be placed on the setRate method. You can do this by using the @ConcurrencyAttribute like so:

@Singleton
public class DiscountRateBean ...{
    @PersistenceContext
    
private EntityManager entityManager;
    
private Rate rate;
    @PostConstruct
    
private void init() ...{
    rate 
= entityManager.find(Rate.class1);
    }

    @PreDestroy
    
private void destroy() ...{
    entityManager.merge(rate);
    }

    @ConcurrencyAttribute(READ_WRITE_LOCK)
    
public void setRate(Rate rate) ...{
    
this.rate = rate;
    }

    @ConcurrencyAttribute(READ_LOCK)
    
public Rate getRate() ...{
    
return rate;
    }

}

For those who are familiar with Doug Lea's work, the READ_LOCK and READ_WRITE_LOCK terminology comes from java.util.concurrent. There are some application shared data that are just read-only. Any locking is really unnecessary in such cases. In such a case, you can create an unsynchronized Singleton like this:
@Singleton
@ConcurrencyAttribute(NO_LOCK) 
// READ_LOCK would also work...
public class DiscountRateBean ...{
    @PersistenceContext
    
private EntityManager entityManager;
    
private Rate rate;
    @PostConstruct
    
private void init() ...{
    rate 
= entityManager.find(Rate.class1);
    }

    
public Rate getRate() ...{
    
return rate;
    }

}

One alternative to @ConcurrencyAttribute(READ_LOCK), @ConcurrencyAttribute(READ_WRITE_LOCK) and @ConcurrencyAttribute(NO_LOCK) being forwarded is @ConcurrencyReadLock, @ConcurrencyReadWriteLock and @ConcurrencyNoLock. To keep consistency with these low-level annotations, @TransactionAttribute would be broken up into @TransactionRequired, @RequiresNewTranscation, @TransactionNotSupported and so on. Some folks have pointed out that this mode of thinking begins to get into "annotation bloat" and adds a new source of complexity. This annotation granularity is also not consistent with Spring and C#.NET declarative transactions. Supporters of this model point out that it is easier to type than @ConcurrencyAttribute(READ_WRITE_LOCK), etc. What do you think?

It may also be entirely possible that you want to manage Singleton concurrency yourself and want the container to be uninvolved other than providing middleware services. This is supported through what is being called bean managed concurrency (a similar idea to bean managed transactions). Here is an example:

@Singleton
@ConcurrencyManagement(BEAN)
public class DiscountRateBean ...{
    @PersistenceContext
    
private EntityManager entityManager;
    
private Rate rate;
    @PostConstruct
    
private void init() ...{
    rate 
= entityManager.find(Rate.class1);
    }

    @PreDestroy
    
private void destroy() ...{
    entityManager.merge(rate);
    }

    
public synchronized void setRate(Rate rate) ...{
    
this.rate = rate;
    }

    
public synchronized Rate getRate() ...{
    
return rate;
    }

}

Notice this time we are managing concurrency ourselves using the synchronized keyword. Since the container will not interfere, you are free to use whatever concurrency management mechanism you like, including but not limited to using the full power of the java.util.concurrent package. For now, the new concurrency management features are limited to EJB 3.1 Singletons, but they could be expanded to cover other bean types.

Singletons will also give you control over lazy/eager loading as well as explicit Singleton dependency management to address load ordering. We won't discuss those features here although you are welcome to comment on that too. Although the specification does not cover clustering support, it is very likely that most vendors will make Singletons cluster-safe (just like Stateful Session Beans).

More EJB 3.1 Features

The two features discussed here are just the tip of the iceberg. There are a number of other very interesting features listed on the JSR agenda. Here are some of the most interesting ones:

  1. Support for direct use of EJBs in the servlet container, including simplified packaging options. The current thought is to allow EJBs in the WEB-INF/classes directory while allowing ejb-jar.xml to reside in the WEB-INF directory, just like the web.xml file. In a similar vein, you would be able to place an EJB jar into the WEB-INF/lib directory.
  2. EJB Timer Service enhancements to support cron-like scheduling, deployment-time timer creation, and Stateful Session Bean timed objects.
  3. Support for stateful web services via Stateful Session Bean web service endpoints.

In addition to these, there are a handful of features that are currently not on the JSR agenda but could be really great:

  1. Further simplification of JMS, JavaMail and database injected resources. For example, you should be able to inject MessageSenders, not just Queues and ConnectionFactory references. Gavin King is a major proponent of this enhancement.
  2. A Service Provider Interface (SPI) for EJB. This will make a number of innovative third-party integrations possible such as iBATIS, Spring, Acegi, Quartz or even Groovy Beans. Bill Burke, Mike Keith and I strongly support this feature.
  3. The ability to add EJB support to a lightweight servlet container like Tomcat. This would be similar to what is already available in the open source world in the form of Embedded JBoss, OpenEJB and EasyBeans. I haven't brought this feature up to the group yet, but will if you think it is good.
  4. The ability to use local transactions in addition to JTA in EJB. I think this would be very useful for smaller web applications that really don't need JTA.

A feature forwarded by Adam Bien, the standardization of JNDI mapping, is also particularly interesting as it will go a long way to enhancing portability across containers. What are your thoughts on this last list? Are the features useful? Should they be pushed harder? Are they more useful than what is on the current agenda?

Your Help is Needed

As you might be able to see, the expert group is trying hard to add useful features to EJB 3.1. We can only go so far on our own though... we need your feedback to tell us if we are on the right track or if we should be pursuing other paths. You can send your feedback directly to the JCP at jsr-318-comments@jcp.org. Feel free to CC me at rrahman@tripodtech.net so I am in the loop. In the coming months, I'll try to present more features to you as we discuss them on the expert group. Until then, wish us good luck!

References

  1. JSR 318: Enterprise JavaBeans 3.1
  2. JSR 299: Web Beans
  3. JSR 316: Java EE 6
分享到:
评论

相关推荐

    EJB3.1深入浅出

    ### EJB 3.1 深入浅出 #### 一、EJB 3.1 的背景与改进 **EJB(Enterprise Java Beans)**是Java Enterprise Edition(Java EE)平台上的服务端组件架构模型,它旨在快速并简化分布式、事务处理、安全性以及可移植...

    EJB3.1cookbook的源代码

    EJB 3.1是其一个重要的版本,相较于3.0,它引入了许多改进和新特性,使得EJB更加易用且更接近轻量级框架的开发体验。这个压缩包中的源代码是《EJB 3.1 Cookbook》一书的配套实例,可以帮助读者深入理解和应用书中...

    EJB3.1_JSR 318-EJB3.1

    - **标题**:“EJB3.1_JSR 318-EJB3.1” - **描述**:此文档是EJB 3.1规范(JSR 318),与EJB 3.0相比,新增的功能包括: - 取消接口要求。 - 引入单例会话Bean(Singleton session bean)。 - 支持异步调用。 -...

    EJB3.1技术培训

    ### EJB3.1技术培训知识点详述 #### 一、EJB3.1概述 **EJB(Enterprise JavaBeans)3.1** 是Java EE平台中的一个重要组成部分,主要用于构建可伸缩、健壮的企业级应用程序。EJB3.1在前代版本的基础上做了大量的...

    EJB 3.1 Cookbook

    《EJB 3.1 Cookbook》是一本针对企业级Java应用开发的专业书籍,主要涵盖了EJB(Enterprise JavaBeans)3.1版本的相关技术。EJB是Java EE(Java Platform, Enterprise Edition)的一部分,用于构建可扩展、安全且...

    _EJB3.1javaFX搭建工程.doc

    【EJB3.1简介】 EJB(Enterprise Java Beans)是Java平台上的一个核心标准,主要用于构建企业级分布式应用程序。EJB3.1是EJB规范的一个版本,它简化了之前版本的复杂性,提高了开发效率。EJB3.1引入了更多的注解驱动...

    EJB 3.1 Core

    EJB 3.1增强了事务管理能力,支持多种事务类型(如`REQUIRED`, `REQUIRES_NEW`, `MANDATORY`等),并且通过`@TransactionAttribute`注解为EJB方法提供事务属性配置。 #### 三、EJB 3.1的要求与限制 EJB 3.1不仅对...

    EJB3.1与JBoss7.1.1在eclipse的实现

    标题《EJB3.1与JBoss7.1.1在eclipse的实现》意味着本文档将介绍如何使用EJB3.1标准在JBoss应用服务器7.1.1版本上进行企业级Java Bean(EJB)的开发,并通过Eclipse集成开发环境进行部署和测试。EJB3.1是一种用于简化...

    EJB 3.1五大模式改进令Java EE 6更好用

    ### EJB 3.1五大模式改进令Java EE 6更好用 在深入解析EJB 3.1的五大改进模式之前,我们首先简要回顾一下EJB(Enterprise Java Beans)的基本概念及其在Java EE平台中的重要性。EJB是Java EE的核心组件之一,旨在...

    EJB.3.1.Cookbook.pdf

    ### EJB 3.1 Cookbook 知识点详解 #### 一、EJB 3.1 概述 **企业 Java Beans (EJB)** 是一种为服务器端应用提供组件架构的 Java 技术。EJB 3.1(Java EE 6 的一部分)是一个重要的里程碑,它在原有基础上进行了...

    j2ee ejb3.1

    **J2EE EJB 3.1:企业级Java组件的增强与演进** Java 2 Platform, Enterprise Edition (J2EE) 是一个用于构建分布式、多层的企业级应用程序的平台,而Enterprise JavaBeans (EJB) 是J2EE的核心组成部分,它提供了一...

    jboss7.1+ejb3.1建立第一个Ejb项目

    本篇文章将指导你如何使用JBoss7.1和EJB3.1在Eclipse3.7环境中创建你的第一个EJB项目。EJB(Enterprise JavaBeans)是一种Java平台上的组件模型,用于构建可扩展的、可靠的、安全的企业级应用。JBoss是Red Hat公司...

    javax.ejb-3.1.2.2.jar下载

    标题中的"javax.ejb-3.1.2.2.jar"是一个特定版本的EJB API的实现,它对应于EJB 3.1规范的2.2次小更新。这个jar文件是开发人员在EJB 3.1环境中开发、测试和部署企业级Java应用程序所必需的依赖库。EJB 3.1是EJB规范的...

    EJB3.1CookbookFreePdfBook.pdf 英文原版

    EJB 3.1 Cookbook – Free Pdf Book

    ejb3.1 cookbook

    标题《EJB3.1 Cookbook》表明这是一本关于企业Java Bean (EJB) 技术的实用指南,其第三版专注于提供一系列解决实际问题的简单而非常有效的方法。EJB是Java EE(现在称为Jakarta EE)的一部分,用于简化基于Java的...

    javax.ejb-3.1.2.2_with-source.zip

    "javax.ejb-3.1.2.2_with-source.zip"是一个包含了javax.ejb-3.1.2.2版本的EJB组件,这个版本支持Java EE 6规范,且提供了源代码供开发者深入学习和调试。 EJB 3.1是EJB规范的一个重要里程碑,它极大地简化了EJB的...

    ejb-3_1-pr-api.zip_EJB a_ejb_ejb api

    EJB 3.1是该规范的一个重要版本,引入了许多改进以提高开发者的生产力和简化API。在这个ejb-3_1-pr-api.zip文件中,我们主要关注的是EJB 3.1的编程模型和API。 EJB 3.1的重要特性包括: 1. **注解驱动的开发**:与...

    Enterprise JavaBeans 3.1

    随着技术的发展,EJB经历了多个版本的迭代,其中EJB 3.1作为第六版的一部分,在功能上有了显著的提升和完善。该版本不仅保持了原有的优点,如简化复杂的企业级应用开发过程,还增加了许多新的特性,以更好地适应现代...

Global site tag (gtag.js) - Google Analytics