??xml version="1.0" encoding="utf-8" standalone="yes"?>
1、用户对应对某个动作的访问权限;
2、用户对应的是那个角Ԍ
3、角色所对应的动作访问权限?BR> 分析可见Q一切都是围l用h讄的,如下图所C:(x)
acl实体关系?BR>
AspectJ是AOP的Java语言的实玎ͼ获得了JavaE序员的q泛x?
关于AspectJ和AOP的具体资料,请从下列链接中查找:(x)
http://www.eclipse.org/aspectj/
http://www.parc.com/research/csl/projects/aspectj/
http://aosd.net/
|上出现了很多讲解AspectJ的资料,但大多是从讲解AspectJ语法开始,然后讲解如何应用AspectJQ如何分Y件开发过E的不同斚wQAspectQ?-LogQSessionQAuthentication and AuthorizationQTransactionQ等{?
初次接触AspectJ的读者看到这些资料(或者语法手册)Q会(x)感到AspectJ有些秘。他们想知道QAspectJ是如何做到这些的QAspectJ是怎样工作的?AspectJ需要特D的q行环境吗?
本文从另一个角度讲解AspectJQ本文从讲解AspectJ的设计思\、运行原理入手,回答上述问题?
本文讲解的主要内容,按照概念的重要程度,排列如下Q?
AspectJ是一个代码生成工PCode GeneratorQ?
AspectJ语法是用来定义代码生成规则的语法。?zhn)如果使用qJava Compiler Compiler (JavaCC)Q?zhn)会(x)发玎ͼ两者的代码生成规则的理忉|人相伹{?
AspectJ有自q语法~译工具Q编译的l果是Java Class文gQ运行的时候,classpath需要包含AspectJ的一个jar文gQRuntime libQ?
AspectJ和xDoclet的比较。AspectJ和EJB Descriptor的比较?
本文的原则是Q只l讲其他资料没有讲到的东西,其他资料讲过的东西,不讲或略讌Ӏ以节省|络资源Q更Z节省大家宝贵的时间。J
2QAspect Oriented Programming (AOP)
本节单介lAOP的概念,解释我们Z么需要AOP?
AOP是Object Oriented ProgrammingQOOPQ的补充?/P>
OOP能够很好地解军_象的数据和封装的问题Q却不能很好的解决AspectQ?斚w"Q分ȝ问题。下面D例具体说明?/P>
比如Q我们有一个BankQ银行)cRBank有两个方法,depositQ存钱)和withdrawQ取钱)?
cdҎ(gu)的定义如下:(x)
Code 2.1 Bank.java
class Bank{
public float deposit(AccountInfo account, float money){
// 增加account账户的钱敎ͼq回账户里当前的钱数
}
public float withdraw(AccountInfo account, float money){
// 减少account账户的钱敎ͼq回取出的钱?BR>}
};
q两个方法涉?qing)到用户的̎戯金等重要信息Q必要非常心Q所以编写完上面的商业逻辑之后Q项目负责h又提Z新的要求--lBankcȝ每个重要Ҏ(gu)加上安全认证Ҏ(gu)?
于是Q我们不得不分别在上面的两个Ҏ(gu)中加入安全认证的代码?
cdҎ(gu)的定义如下:(x)Q新增加的代码用不同的背景标出)
Code 2.2 Bank.java
class Bank{
public float deposit(AccountInfo account, float money){
// 验证account是否为合法用?BR> // 增加account账户的钱敎ͼq回账户里当前的钱数
}
public float withdraw(AccountInfo account, float money){
// 验证account是否为合法用?BR> // 减少account账户的钱敎ͼq回取出的钱?BR>}
};
q两个方法都需要操作数据库Qؓ(f)了保持数据完整性,目负责人又提出了新的要?-lBankcȝ每个操作数据库的Ҏ(gu)加上事务控制?
于是Q我们不得不分别在上面的两个Ҏ(gu)中加入安全认证的代码?
cdҎ(gu)的定义如下:(x)Q新增加的代码用不同的背景标出)
Code 2.3 Bank.java
class Bank{
public float deposit(AccountInfo account, float money){
// 验证account是否为合法用?BR> // Begin Transaction
// 增加account账户的钱敎ͼq回账户里当前的钱数
// End Transaction
}
public float withdraw(AccountInfo account, float money){
// 验证account是否为合法用?BR> // Begin Transaction
// 减少account账户的钱敎ͼq回取出的钱?BR> // End Transaction
}
};
我们看到Q这些与商业逻辑无关的重复代码遍布在整个E序中。实际的工程目中涉?qing)到的类和函敎ͼq远不止两个。如何解册U问题?
我们首先来看看OOP能否解决q个问题?
我们利用Design Pattern的Template PatternQ可以抽Z个框Ӟ改变上面的例子的整个设计l构?
cdҎ(gu)的定义如下:(x)
Code 2.4 Base.java
abstract class Base{
public float importantMethod(AccountInfo account, float money){
// 验证account是否为合法用?BR> // Begin Transaction
float result = yourBusiness(account, money)
// End Transaction
return result;
}
protected abstract float yourBusiness(AccountInfo account, float money);
};
Code 2.5 BankDeposit.java
class BankDeposit extends Base{
protected float yourBusiness(AccountInfo account, float money){
// 增加account账户的钱敎ͼq回账户里当前的钱数
}
};
Code 2.6 BankWithdraw.java
class BankWithdraw extends Base{
protected float yourBusiness(AccountInfo account, float money){
// 减少account账户的钱敎ͼq回取出的钱?BR>}
};
q里我们用一U很勉强的方法实C认证和事务代码的重用。而且Q有心的读者可能会(x)注意刎ͼq种Ҏ(gu)的前提是Q强制所有的Ҏ(gu)都遵守同L(fng)signature?
如果有一个{账方法transfer(AccountInfo giver, AccountInfo receiver, float money)Q由于transferҎ(gu)的signature不同于yourBusiness的signatureQ这个方法无法用上面的框架?
q个例子中提到的认证Q事务等斚wQ就是AOP所兛_的Aspect?
AOP是Z解决q种问题而出现的。AOP的目的就?-Separation of Aspects (or Separation of Concerns).
下面的章节,解释EJB DescriptorQAspectJQxDoclet{工具如何解决Separation of Aspects的问题?
3QEJB Descriptor
如果我们使用EJB实现上面的例子,Bankcd以作Z个Stateless Session Bean实现?
在Bank的代码中只用考虑商业逻辑Q不用考虑认证和事务等斚w?
认证和事务等斚w在EJB Descriptor中定义,由EJB Container提供q些斚w的实现?
我们来看一下,如何使用EJB Descriptor描述上面的例子?
EJB Descriptor包括一个ejb-jar.xml文g。ejb-jar.xml文g包含两大部分Qenterprise-beans和assembly-descriptor部分。enterprise-beans部分包含EJB的定?-JNDI NameQEJB Home, Interface, Bean Class Path{;assembly-descriptor部分包括配置信息的定?-安全角色Q事务控制等{?
下面l出上面例子对应的模拟EJB Descriptor?
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>Bank</ejb-name>
?BR> <ejb-class>example.Bank</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<security-role-ref>
<role-name>bank-account</role-name>
</security-role-ref>
</session>
</enterprise-beans>
<assembly-descriptor>
<security-role>
<role-name>bank-account</role-name>
</security-role>
<method-permission>
<role-name>employee</role-name>
<method>
<ejb-name>Bank</ejb-name>
<method-name>deposit</method-name>
</method>
<method>
<ejb-name>Bank</ejb-name>
<method-name>withdraw</method-name>
</method>
</method-permission>
<container-transaction>
<method>
<ejb-name>Bank</ejb-name>
<method-name>deposit</method-name>
</method>
<method>
<ejb-name>Bank</ejb-name>
<method-name>withdraw</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
本文后面?x)讲到如何用AspectJ实现上例中的Separation of Aspects?
读者可以比较一下AspectJ语法和EJB Descriptor定义之间的对应关pR?
两者都提供了类名、方法名的匹配规则,能够把类的方法映到认证Q事务等AspectQ方面)?
4QAspectJ
q一节我们来看看AspectJ如何实现上例中的Separation of Aspects?
使用AspectJQ我们不用对原有的代码做M修改Q就可以Z码提供不同的AspectQ方面)--比如Q认证,事务{?
我们只需要提供两个不同的Aspect--认证Aspect和事务Aspect?
Code 4.1 AuthAspect.java
aspect AuthAspect{
pointcut bankMethods() : execution (* Bank.deposit(?) || execution (* Bank. withdraw (?);
Object around(): bankMethods(){
// 验证account是否为合法用?/P>
return proceed();
}
};
Code 4.2 TransactionAspect.java
aspect TransactionAspect{
pointcut bankMethods() : execution(* Bank.deposit(?) || execution (* Bank. withdraw (?);
Object around(): bankMethods(){
// Begin Transaction
Object result = proceed();
// End Transaction
return result;
}
};
如果(zhn)暂时不能理解这D代码,没有关系Q后面会(x)讲到Q这些aspect的定义,不过是定义了一些代码生成规则?
我们用AspectJ~译器编译B(ti)ank文g和含有aspect的这个文Ӟ出来的结果就是带有安全认证和事务处理的BankcR编译出来的q个Bankc调用了AspectJ Runtime LibQ所以,如果你要q行q个Bankc,你需要把AspectJ Runtime Lib讄在你的classpath里面?
我们来看看,AspectJ~译器ؓ(f)我们做了什么事情?
首先QAspectJ从文件列表里取出所有的文g名,然后dq些文gQ进行分析?
AspectJ发现一些文件含有aspect的定义,在这个例子里Q就是AuthAspect和TransactionAspect的定义;q些aspect是代码生成规则?
AspectJҎ(gu)q些aspect代码生成规则Q修Ҏ(gu)加你的源代码。在q个例子里,是修改dBank文g?
AspectJdAuthAspect的定义,发现了一个pointcut--bankMethods()Q这个pointcut的定义是execution(* Bank.deposit(?) || execution(* Bank. withdraw (?)Q表C所有对Bankcȝdeposit和withdrawҎ(gu)的执行点?
AspectJl箋dAuthAspect的定义,发现了一个around()Q这在AspectJ中叫做AdviceQ我不明白ؓ(f)什么叫q个名字Q不q没关系Q我们只要知道它是干什么的p了。Advice允许你在某个cȝҎ(gu)的调用之前或调用之后Q加入另外的代码。Code 4.1所CZ码中的around()? // 验证account是否为合法用?部分Q就是要加入的代码。这D代码要加在哪里呢?around()后面跟了一个pointcut--bankMethods()。根据这个pointcutQAspectJ?x)把q段代码加入到Bank.deposit和Bank.withdraw两个Ҏ(gu)的执行之前。达到的效果如同Code 2.2所C?
AspectJdTransactionAspect的定义,象第Q?Q步一P发现了发C一个pointcut--bankMethods()?
AspectJl箋dAuthAspect的定义,发现了一个around()。这ơAspectJ?Begin Transaction"?End Transaction"两段代码加在Bank.deposit和Bank. withdraw两个Ҏ(gu)的执行前后。达到的效果如同Code 2.3所C?
如何验证q一点?(zhn)可以到 http://www.eclipse.org/aspectj/下蝲安装AspectJQ编译里面的SampleQ把~译l果反编译一下,可以看到AspetJ自动生成的代码?
我们看到QAspectJ是一U代码自动生成工兗你~写一D通用的代码,比如认证斚w的代码,事务斚w的代码,然后Ҏ(gu)AspectJ语法定义一套代码生成规则(aspect定义Q,AspectJ׃(x)帮助你自动把q段通用代码分布到对应的代码里面去,单快P无遗策?
无独有偶Q一个著名的~译器生成工?-Java Compiler Compiler (JavaCC)Q也采用了非常相似的代码生成机制。JavaCC允许你在语法定义规则文g中,加入你自qJava代码Q用来处理读入的各种语法元素?
AspectJ令你的代码更_Q结构更良好。AspectJ的好处,我就不多说了Q网上很多精彩的文章探讨AspectJ的各U用途?
下面介绍一个著名的代码自动生成?-xDocletQ和EJB DescriptorQAspectJ之间的联pd比较?
5QxDoclet
我们知道QDoclet用来生成JavadocQxDoclet是Doclet的扩展,不仅仅能生成JavadocQ还能够生成源代码和配置信息{?
Doclet和xDoclet的工作原理,是处理源代码中的注释中的tagQ生成相应的信息。这些tag都以@开_(d)你可以自己定义tag和对tag的处理,生成自定义的信息?
Q这里提一下Apache Maven Project。Maven是一UProject Build工具。用Mavenq行理的项目,能够同时生成Javadoc和XRef。XRef是Source Code Cross Reference?
JBoss利用xDoclet为EJB自动生成EJB Home和EJB Object Interface源文Ӟ和EJB Descriptor文g?
在Sourceforge.net上看C个叫做Barter的开源项目,利用xDoclet为类Ҏ(gu)生成AspectJ代码?
h意,EJB Descriptor和AspectJ都是把方斚w面的Aspects集中在一处进行管理,而xDoclet的思想是处理散布在源代码中的各Utag?
xDoclet在生成EJB Descriptor和AspectJ{方面的应用Q正应了中国的一句古?-分久必合Q合久必分?
6Qȝ
开源项目的出现Q打破了软g技术领域的众多壁垒Q推动Y件技术进E的日新月异?
同时Q一些新名词Q新概念也层ZIP令hD~ؕQ无所适从。其实,很多东西都是换汤不换药,我们理解应用q些新技术的时候,要抓住本质,要破除迷信,破除MZؓ(f)的神U感?
举个例子Q现在炒作的很热的一些概念,"Web Service"Q还?Grid Computation"Q网D)Q都是基于原有的各种技术发展出来的。媒体和技术文章不应该Zؓ(f)地制造Q何神U感?
互联|时代的权威Q不是说出来的,而是做出来的?
另外Q围l着一些有前途的新技术,M(x)出现大量?快速入门手?Q有些简直就是对该技术帮助文档的译Q而且Q有隑ֺ的地Ҏ(gu)有翻译出来,大家都明白的地方译得非常详,详尽C没有必要的地步。这U因为市场需求而生的应景时文Q大量地出现在技术文章领域?
W者对本文的期望是Q决不迷信,决不重复。ƈ试图引入一U洁净的,毫无废话的文风。笔者期待一针见血的驳斥和批评?
Enjoy it. J
Thanks.
关于作?BR>王v?普通程序员?
Powered by Open Source。致力于做一个ArchitectQSolution ProviderQBest Practice Provider?
希望有一天,有够的旉Q精力和能力的时候,把自己有限的一w所学的一点东西全部A(ch)献给Open Source Project?
最ȝ的是必须了解每一个标{属性,只能照着例子试!
最多的属性有Qname,value,propertyq三个家伙很Ҏ(gu)hQ必L旉试ȝ才行Q?BR> 有哪位搞得很清楚了请替我补充Q?/P>