EJB 3.0+Aspect实现声明性编程初步
2008-02-23 07:59:38来源:互联网 阅读 ()
一、 引言
在我们共同寻求进一步提高软件开发生产性能的方法的过程中,我们-作为Java社团成员-一般都转向J2EE来提供针对企业开发中更具挑战性的技术问题如分布式事务管理、并发性和对象分布等的解决方案。其背后的指导思想-这些复杂的企业服务能被应用程序服务器供应商所实现并能为商业开发者所平衡-的确是一种很好的思想。J2EE,具体地说是EJB,已成功地提供了一个平台-在其上构建企业Java应用程序。
这其中部分的成功是由于能够进行声明性编程-一种程序开发方式-用这种方式,你可以声明基础结构服务而不是用商业逻辑明确地编码从而使代码散布于各处。EJB已经证明了这种编程方式的价值-通过允许企业问题例如事务和安全被用一种发布描述符所声明并为容器所处理。
然而,在过去的岁月中,越来越多的开发者认识到EJB在团队的生产效率方面给它自己带来新的大量的挑战-每个EJB必须伴随多个接口,以一种发布描述符描述,经由JNDI被存取,等等。而在容器外EJB上进行单元测试也带来另外的困难,如今EJB已不再把重点放在单纯的面向对象开发上。
请注意,为阅读本文您需具备如下工具:
·Java 2 SDK 1.5
·Maven 2.0 Beta 2
EJB 3.0的目标在于从以下几个方面使企业开发更为容易:
·通过引入元数据注解来实现声明性请求企业服务
·经由注解实现依赖性/资源注入
·实现企业beans与EJB特定接口的解耦
·经由轻量级的对象关系映射实现持续性存储的简化
这对于EJB开发者来说尤如一股春风-一直以来,他们竭力地从事开发、测试和维护EJB。利用EJB 3.0写一个企业bean现在变得很容易,就如用特定的注解创建一个POJO(传统的Java对象)以把它标明为一个EJB并请求企业服务。下面是一个来自于EJB 3.0 Public Draft中EJB的例子:
@Stateful
public class CartBean implements ShoppingCart
{
private float total;
private Vector productCodes;
public int someShoppingMethod(){...};
...
}
EJB 3.0声明中实质上指明开发者需要的不是一重量级的、"一次发布满足所有"的解决方案,而是一个轻量级的、容易使用的解决方案-为开发者提供一定范围的企业服务。为此,EJB 3.0所提供的最重要的方法之一就是实现企业beans与EJB API的解耦。并且,此解决方案还带来令人感兴趣的衍生-EJB现在不仅能够运行在不同的EJB容器上,而且还能运行于任何应用程序框架内部-这些框架必须能够识别EJB 3.0(JSR 220)和用于声明企业服务的普通注解(JSR 250)。
本文没有提供关于声明性编程、EJBs、方面或注解的深度探索。相反,而只是分析一下这些技术之间的相互关系并讨论如何把它们用一种新的方式结合起来以简化应用程序开发。
在本文中,你将会学习到如何编写一个EJB 3.0兼容的bean并且通过创建几个简单的方面使其具有声明性事务管理、安全和资源注入等功能。我希望您能从这个练习中得到以下的受益:
·学习方面的三个实际应用(依赖性注入、安全和事务)。
·熟悉EJB 3.0及其背后的思想。
·认识到怎样实现EJB与特定API的解耦以允许EJB 3.0兼容的服务能够以轻量级实现而不是仅由EJB来提供。
二、 实例应用程序-航班订购
在整个后面的讨论中,你将学习到一个航班订购系统的实现-它使用方面和注解来实现依赖性注入、安全和事务管理。该应用程序仅执行两项功能:它允许用户搜索航班(图1),然后订购一次旅行(图2)。这两个操作都将被进行安全处理以仅允许能被识别的用户来执行它们。另外,既然"订购旅行"操作包含订购两个航班(外出和返回航班),那么需要把该操作创建为事务性的-如,两个订购将作为一个工作单元要么都成功要么都失败。
图1.航班查询:首先,用户查找满足他们的指定标准的航班。
图2.航班订购:接下来,用户订购一个外出航班和一个返回航班。两个订购要么都成功要么都失败。
这个简单的Web应用程序包含几个servlet、一个服务外观和一个DAO层(见图3)。
资源配置、安全性和事务管理等横切关注点将由方面(用AspectJ 1.5 M3实现)所提供以实现在Java 5注解中所声明的注入行为。
图3.航班订购系统架构:这个航班订购系统包括三个主要组成组件-它们联合起来共同完成用户请求。 三、 资源注入
EJB 3.0草案声明中允许资源经由@Resource注解来声明(这一决定定义在草案普通注解声明中)并且被容器注入进你的EJB。依赖性注入是一项技术-使用这种技术,一个对象外部的实体而不是显式地为该对象所创建的实体能够提供(注入)一个对象的依赖性。它有时被描述为好莱坞原则-这开玩笑似地意味着"不要给我们打电话,我们会给你打电话的"。
以TravelAgencyServiceImpl类为例-这个类为了持续性存储一些数据需要找到一个IFlightDAO接口的实现。传统地,这是经由一个工厂、singleton、服务定位器或一些另外的定制解决方案来实现的。其中,一个可能的解决方案看上去如下所示:
public class TravelAgencyServiceImpl implements ITravelAgencyService
{
public IFlightDAO flightDAO;
public TravelAgencyServiceImpl()
{ flightDAO = FlightDAOFactory.getInstance().getFlightDAO(); }
public void bookTrip(long outboundFlightID, long returnFlightID, int seats)
throws InsufficientSeatsException
{
reserveSeats(outboundFlightID, seats);
reserveSeats(returnFlightID, seats);
}
}
你已看到,这个实现包含创建一个特定的工厂类-它很可能读取存储在某处的配置信息以了解要创建IFlightDAO的实现方式。如果不是让服务显式地创建它的由容器所注入的依赖性,那么配置细节和对象创建将被代理到容器上。这允许一个应用程序中的组件能够被容易地连接到一起-用不同的配置并且消除大量老式的singleton和工厂代码。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:使用jsp生成彩色汉字验证码
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash