作者 Reza Rahman 摘自
http://www.theserverside.comThis
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.class, 1);
}
@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.class, 1);
}
@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.class, 1);
}

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.class, 1);
}
@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:
- 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.
- EJB Timer Service enhancements to
support cron-like scheduling, deployment-time timer creation, and
Stateful Session Bean timed objects.
- 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:
- 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.
- 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.
- 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.
- 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
- JSR 318: Enterprise JavaBeans 3.1
- JSR 299: Web Beans
- JSR 316: Java EE 6
分享到:
相关推荐
### EJB 3.1 深入浅出 #### 一、EJB 3.1 的背景与改进 **EJB(Enterprise Java Beans)**是Java Enterprise Edition(Java EE)平台上的服务端组件架构模型,它旨在快速并简化分布式、事务处理、安全性以及可移植...
EJB 3.1是其一个重要的版本,相较于3.0,它引入了许多改进和新特性,使得EJB更加易用且更接近轻量级框架的开发体验。这个压缩包中的源代码是《EJB 3.1 Cookbook》一书的配套实例,可以帮助读者深入理解和应用书中...
- **标题**:“EJB3.1_JSR 318-EJB3.1” - **描述**:此文档是EJB 3.1规范(JSR 318),与EJB 3.0相比,新增的功能包括: - 取消接口要求。 - 引入单例会话Bean(Singleton session bean)。 - 支持异步调用。 -...
### EJB3.1技术培训知识点详述 #### 一、EJB3.1概述 **EJB(Enterprise JavaBeans)3.1** 是Java EE平台中的一个重要组成部分,主要用于构建可伸缩、健壮的企业级应用程序。EJB3.1在前代版本的基础上做了大量的...
《EJB 3.1 Cookbook》是一本针对企业级Java应用开发的专业书籍,主要涵盖了EJB(Enterprise JavaBeans)3.1版本的相关技术。EJB是Java EE(Java Platform, Enterprise Edition)的一部分,用于构建可扩展、安全且...
### EJB3.1讲解 #### EJB概要 ##### EJB基本概念 EJB(Enterprise JavaBeans)是由Sun Microsystems提出的、面向企业级应用的一种组件模型。它旨在为开发复杂的企业级应用程序提供一种标准化的方式。在EJB的概念...
【EJB3.1简介】 EJB(Enterprise Java Beans)是Java平台上的一个核心标准,主要用于构建企业级分布式应用程序。EJB3.1是EJB规范的一个版本,它简化了之前版本的复杂性,提高了开发效率。EJB3.1引入了更多的注解驱动...
EJB 3.1增强了事务管理能力,支持多种事务类型(如`REQUIRED`, `REQUIRES_NEW`, `MANDATORY`等),并且通过`@TransactionAttribute`注解为EJB方法提供事务属性配置。 #### 三、EJB 3.1的要求与限制 EJB 3.1不仅对...
标题《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的五大改进模式之前,我们首先简要回顾一下EJB(Enterprise Java Beans)的基本概念及其在Java EE平台中的重要性。EJB是Java EE的核心组件之一,旨在...
### EJB 3.1 Cookbook 知识点详解 #### 一、EJB 3.1 概述 **企业 Java Beans (EJB)** 是一种为服务器端应用提供组件架构的 Java 技术。EJB 3.1(Java EE 6 的一部分)是一个重要的里程碑,它在原有基础上进行了...
**J2EE EJB 3.1:企业级Java组件的增强与演进** Java 2 Platform, Enterprise Edition (J2EE) 是一个用于构建分布式、多层的企业级应用程序的平台,而Enterprise JavaBeans (EJB) 是J2EE的核心组成部分,它提供了一...
"javax.ejb-3.1.2.2_with-source.zip"是一个包含了javax.ejb-3.1.2.2版本的EJB组件,这个版本支持Java EE 6规范,且提供了源代码供开发者深入学习和调试。 EJB 3.1是EJB规范的一个重要里程碑,它极大地简化了EJB的...
本篇文章将指导你如何使用JBoss7.1和EJB3.1在Eclipse3.7环境中创建你的第一个EJB项目。EJB(Enterprise JavaBeans)是一种Java平台上的组件模型,用于构建可扩展的、可靠的、安全的企业级应用。JBoss是Red Hat公司...
标题中的"javax.ejb-3.1.2.2.jar"是一个特定版本的EJB API的实现,它对应于EJB 3.1规范的2.2次小更新。这个jar文件是开发人员在EJB 3.1环境中开发、测试和部署企业级Java应用程序所必需的依赖库。EJB 3.1是EJB规范的...
EJB 3.1 Cookbook – Free Pdf Book
标题《EJB3.1 Cookbook》表明这是一本关于企业Java Bean (EJB) 技术的实用指南,其第三版专注于提供一系列解决实际问题的简单而非常有效的方法。EJB是Java EE(现在称为Jakarta EE)的一部分,用于简化基于Java的...
EJB 3.1是该规范的一个重要版本,引入了许多改进以提高开发者的生产力和简化API。在这个ejb-3_1-pr-api.zip文件中,我们主要关注的是EJB 3.1的编程模型和API。 EJB 3.1的重要特性包括: 1. **注解驱动的开发**:与...
随着技术的发展,EJB经历了多个版本的迭代,其中EJB 3.1作为第六版的一部分,在功能上有了显著的提升和完善。该版本不仅保持了原有的优点,如简化复杂的企业级应用开发过程,还增加了许多新的特性,以更好地适应现代...