| |
用EJB 3.0开发企业级Bean组件初体验 |
|
时间: 2005-12-27 来自:天极开发 |
 |
|
|
三、无状态会话Beans
与EJB 3.0规格说明书中的其它一些企业bean组件一样,无状态会话beans是一些实现了一个商业接口的POJO。以我们的音乐店为例:该音乐店实现在用户浏览时对各种类型的音频和视频的查询功能。对这个音乐店来说,实现这一功能的一个简单的接口实现可以如下编写:
public interface IMusicStore{ public List<Genre> listGenres(); public Genre findGenreById(int id); public Artist findArtistById(int id); public Product findProductById(int id); public void checkOut(IShoppingCart cart); } | 并且下面是这种情况的一个简单实现:
public class MusicStore implements IMusicStore{ public List<Genre> listGenres() { return MusicStoreDAO.getInstance().listGenres(); } public Genre findGenreById(int id) { return MusicStoreDAO.getInstance().findGenreById(id); } public Artist findArtistById(int id) { return MusicStoreDAO.getInstance().findArtistById(id); } public Product findProductById(int id) { return MusicStoreDAO.getInstance().findProductById(id); } public void checkOut(IShoppingCart cart) { ... } } | 在EJB 2.x中,如果你想要利用企业服务的优点,如声明性事务管理或对象分布,那么你必须修改该音乐店以实现javax.ejb.SessionBean接口以及在这个接口中定义的方法;另外,还要创建本地的和远程的bean和home接口。
在EJB 3.0中,一个类要被扩展为一个无状态会话bean必须满足下面两个基本要求:
1. 实现至少一个商业接口。
2. 被用@javax.ejb.Stateless注解所注解。
一个商业接口仅是一个普通的Java接口。其中,java.io.Serializable和java.io.Externalizable接口都被自动地忽略,因为这些都是在javax.ejb包中的接口。如果只有一个接口被指定,那么它就被假定为一个本地接口。这是在规格说明书的配置中唯一的一个例子。如果这个bean有多于一个的商业接口,那么每个接口必须被显式地定义为本地的或远程的-通过注解这个bean类或者通过注解这些接口本身。
因此,为了把MusicStore类做成为一个无状态的会话bean,仅需做一个改变。你必须用@Stateless注解来注解它。
@Stateless public class MusicStore implements IMusicStore{ ...} | 与EJB 3.0相关的另一个主要变化实际上是一个J2EE 1.5规格说明书中的变化-依赖性注入。J2EE 1.5规格说明书要求,J2EE应用程序客户、企业beans和web组件都可以存取一个JNDI命名环境。该命名环境可以被存取,或者通过显式的JNDI查找调用或通过指定容器将自动注入依赖性的注解。这意味着,现在你可以通过一个如下的简单注解声明一个对一个EJB或其它由容器管理的资源的依赖性:
import com.devx.musicstore.IMusicStore; public abstract class AbstractStoreAction extends Action{ @EJB protected IMusicStore store; ... } | 就是这样!该容器将把接口ImusicStore的一个实现注入到该行为中,而该行为可以使用这个存储对象,就象它是一个简单的POJO一样。
作者注:
在JBoss4.0.3 版本中还没有实现针对web组件的资源注入功能,尽管这种支持即将出现(http://jira.jboss.com/jira/browse/EJBTHREE-212)。该实例代码包含一个方面-用JBoss AOP写成,它实现了依赖性注入。
其实背后真正进行的是,这个注解指定把一个到类型IMusicStore的EJB参考注入到store字段中。该依赖性的目标并没有指定,因此必须由发布者来提供-就象使用传统型的资源参考一样。如果没有指定依赖性名字(如上面例子中所示),那么就假定是使用类的完全限制的命名。在上面的实例中,这将是java:comp/env/com.devx.musicstore.IMusicStore。
作者注 在缺省地使用EJB参考的名字时,在有关是否使用不限制的或完全限制的类命名的问题上在EJB 3.0和J2EE 1.5规格说明书存在一些歧义。EJB 3.0公共草案指定不限制的bean类命名,而J2EE 1.5草案显示了一个完全限制的命名示例。JBoss实现使用完全限制的命名。
作为选择,你可以如下方式来进一步提练这种依赖性的声明:
public abstract class AbstractStoreAction extends Action{ @EJB( name = "ejb/musicStore", beanName = "store1", BusinessInterface = com.devx.musicstore.IMusicStore.class ) protected IMusicStore store; ... } | 在此,对EJB参考的存取是通过在java:comp/env/ejb/musicStore的JNDI实现的。
|
|
|
|
|
|
|
|