﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-acmr-java-随笔分类-Thinking in work</title><link>http://www.blogjava.net/lgcpeter/category/2961.html</link><description>生活在北京，感觉北京不是很适合生活，适合做java</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 03:57:31 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 03:57:31 GMT</pubDate><ttl>60</ttl><item><title>Pow2ACL学习笔记之一</title><link>http://www.blogjava.net/lgcpeter/archive/2005/08/27/11315.html</link><dc:creator>freshboy</dc:creator><author>freshboy</author><pubDate>Sat, 27 Aug 2005 07:06:00 GMT</pubDate><guid>http://www.blogjava.net/lgcpeter/archive/2005/08/27/11315.html</guid><wfw:comment>http://www.blogjava.net/lgcpeter/comments/11315.html</wfw:comment><comments>http://www.blogjava.net/lgcpeter/archive/2005/08/27/11315.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lgcpeter/comments/commentRss/11315.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lgcpeter/services/trackbacks/11315.html</trackback:ping><description><![CDATA[<P>一直以来想做一个用上一些开源成熟框架的论坛，往往在权限这一块卡住，有幸碰到Pow2ACL这个开源项目，于是分几次研究一下，作为自己通用代码的一个收藏和积累。<BR>Pow2ACL&nbsp; 是实现访问控制列表(ACL)的一个java包。<BR>主要是对三个对象方面的控制：用户，角色和访问权限。<BR>控制动作主要是：<BR>1、用户对应对某个动作的访问权限；<BR>2、用户对应的是那个角色；<BR>3、角色所对应的动作访问权限。<BR>&nbsp;&nbsp; 分析可见，一切都是围绕用户来设置的，如下图所示：<BR><IMG src="file:///E:/netdown/pow2acl_20020411/pow2acl/var/db/erDiagram.png"><BR></P>
<P align=center>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; acl实体关系图<BR></P><img src ="http://www.blogjava.net/lgcpeter/aggbug/11315.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lgcpeter/" target="_blank">freshboy</a> 2005-08-27 15:06 <a href="http://www.blogjava.net/lgcpeter/archive/2005/08/27/11315.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>what is AspectJ?(转)</title><link>http://www.blogjava.net/lgcpeter/archive/2005/08/26/11214.html</link><dc:creator>freshboy</dc:creator><author>freshboy</author><pubDate>Fri, 26 Aug 2005 08:00:00 GMT</pubDate><guid>http://www.blogjava.net/lgcpeter/archive/2005/08/26/11214.html</guid><wfw:comment>http://www.blogjava.net/lgcpeter/comments/11214.html</wfw:comment><comments>http://www.blogjava.net/lgcpeter/archive/2005/08/26/11214.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lgcpeter/comments/commentRss/11214.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lgcpeter/services/trackbacks/11214.html</trackback:ping><description><![CDATA[<P>网上出现了很多讲解AspectJ的资料，但大多是从讲解AspectJ语法开始,本文从另一个角度讲解AspectJ，作者着重介绍了AspectJ的设计思路和运行原理。<BR>1. 序<BR>Aspect Oriented Programming (AOP)是近来一个比较热门的话题。 </P>
<P>AspectJ是AOP的Java语言的实现，获得了Java程序员的广泛关注。 </P>
<P>关于AspectJ和AOP的具体资料，请从下列链接中查找： </P>
<P><A href="http://www.eclipse.org/aspectj/">http://www.eclipse.org/aspectj/</A> <BR><A href="http://www.parc.com/research/csl/projects/aspectj/">http://www.parc.com/research/csl/projects/aspectj/</A> <BR><A href="http://aosd.net/">http://aosd.net/</A> </P>
<P>网上出现了很多讲解AspectJ的资料，但大多是从讲解AspectJ语法开始，然后讲解如何应用AspectJ，如何分离软件开发过程的不同方面（Aspect）--Log，Session，Authentication and Authorization，Transaction，等等。 </P>
<P>初次接触AspectJ的读者看到这些资料（或者语法手册），会感到AspectJ有些神秘。他们想知道，AspectJ是如何做到这些的？AspectJ是怎样工作的？AspectJ需要特殊的运行环境吗？ </P>
<P>本文从另一个角度讲解AspectJ，本文从讲解AspectJ的设计思路、运行原理入手，回答上述问题。 </P>
<P>本文讲解的主要内容，按照概念的重要程度，排列如下： </P>
<P>AspectJ是一个代码生成工具（Code Generator）。 <BR>AspectJ语法就是用来定义代码生成规则的语法。您如果使用过Java Compiler Compiler (JavaCC)，您会发现，两者的代码生成规则的理念惊人相似。 <BR>AspectJ有自己的语法编译工具，编译的结果是Java Class文件，运行的时候，classpath需要包含AspectJ的一个jar文件（Runtime lib）。 <BR>AspectJ和xDoclet的比较。AspectJ和EJB Descriptor的比较。 <BR>本文的原则是，只细讲其他资料没有讲到的东西，其他资料讲过的东西，不讲或略讲。以节省网络资源，更为了节省大家宝贵的时间。J </P>
<P>2．Aspect Oriented Programming (AOP)<BR>本节简单介绍AOP的概念，解释我们为什么需要AOP。 </P>
<P>AOP是Object Oriented Programming（OOP）的补充。</P>
<P>OOP能够很好地解决对象的数据和封装的问题，却不能很好的解决Aspect（"方面"）分离的问题。下面举例具体说明。</P>
<P>比如，我们有一个Bank（银行）类。Bank有两个方法，deposit（存钱）和withdraw（取钱）。 </P>
<P>类和方法的定义如下： </P>
<P><BR>Code 2.1 Bank.java<BR>class Bank{<BR>public float deposit(AccountInfo account, float money){<BR>&nbsp; // 增加account账户的钱数，返回账户里当前的钱数<BR>}</P>
<P>public float withdraw(AccountInfo account, float money){<BR>&nbsp; // 减少account账户的钱数，返回取出的钱数<BR>}<BR>};</P>
<P>&nbsp;</P>
<P><BR>这两个方法涉及到用户的账户资金等重要信息，必须要非常小心，所以编写完上面的商业逻辑之后，项目负责人又提出了新的要求--给Bank类的每个重要方法加上安全认证特性。 </P>
<P>于是，我们不得不分别在上面的两个方法中加入安全认证的代码。 </P>
<P>类和方法的定义如下：（新增加的代码用不同的背景标出） </P>
<P><BR>Code 2.2 Bank.java<BR>class Bank{<BR>public float deposit(AccountInfo account, float money){<BR>&nbsp; // 验证account是否为合法用户<BR>&nbsp; // 增加account账户的钱数，返回账户里当前的钱数<BR>}</P>
<P>public float withdraw(AccountInfo account, float money){<BR>&nbsp; // 验证account是否为合法用户<BR>&nbsp; // 减少account账户的钱数，返回取出的钱数<BR>}<BR>};</P>
<P>&nbsp;</P>
<P><BR>这两个方法都需要操作数据库，为了保持数据完整性，项目负责人又提出了新的要求--给Bank类的每个操作数据库的方法加上事务控制。 </P>
<P>于是，我们不得不分别在上面的两个方法中加入安全认证的代码。 </P>
<P>类和方法的定义如下：（新增加的代码用不同的背景标出） </P>
<P><BR>Code 2.3 Bank.java<BR>class Bank{<BR>public float deposit(AccountInfo account, float money){<BR>&nbsp; // 验证account是否为合法用户<BR>&nbsp; // Begin Transaction<BR>&nbsp; // 增加account账户的钱数，返回账户里当前的钱数<BR>&nbsp; // End Transaction<BR>}</P>
<P>public float withdraw(AccountInfo account, float money){<BR>&nbsp; // 验证account是否为合法用户<BR>&nbsp; // Begin Transaction<BR>&nbsp; // 减少account账户的钱数，返回取出的钱数<BR>&nbsp; // End Transaction<BR>}<BR>};</P>
<P>&nbsp;</P>
<P><BR>我们看到，这些与商业逻辑无关的重复代码遍布在整个程序中。实际的工程项目中涉及到的类和函数，远远不止两个。如何解决这种问题？ </P>
<P>我们首先来看看OOP能否解决这个问题。 </P>
<P>我们利用Design Pattern的Template Pattern，可以抽出一个框架，改变上面的例子的整个设计结构。 </P>
<P>类和方法的定义如下： </P>
<P><BR>Code 2.4 Base.java<BR>abstract class Base{<BR>public float importantMethod(AccountInfo account, float money){<BR>&nbsp; // 验证account是否为合法用户<BR>&nbsp; // Begin Transaction<BR>&nbsp; <BR>&nbsp; float result = yourBusiness(account, money)</P>
<P>&nbsp; // End Transaction<BR>&nbsp; return result;&nbsp;<BR>}</P>
<P>protected abstract float yourBusiness(AccountInfo account, float money);<BR>};</P>
<P>Code 2.5 BankDeposit.java<BR>class BankDeposit extends Base{ <BR>protected float yourBusiness(AccountInfo account, float money){<BR>&nbsp; // 增加account账户的钱数，返回账户里当前的钱数<BR>}<BR>};</P>
<P>Code 2.6 BankWithdraw.java<BR>class BankWithdraw extends Base{ <BR>protected float yourBusiness(AccountInfo account, float money){<BR>&nbsp; // 减少account账户的钱数，返回取出的钱数<BR>}<BR>};</P>
<P>&nbsp;</P>
<P><BR>这里我们用一种很勉强的方法实现了认证和事务代码的重用。而且，有心的读者可能会注意到，这种方法的前提是，强制所有的方法都遵守同样的signature。 </P>
<P>如果有一个转账方法transfer(AccountInfo giver, AccountInfo receiver, float money)，由于transfer方法的signature不同于yourBusiness的signature，这个方法无法使用上面的框架。 </P>
<P>这个例子中提到的认证，事务等方面，就是AOP所关心的Aspect。 </P>
<P>AOP就是为了解决这种问题而出现的。AOP的目的就是--Separation of Aspects (or Separation of Concerns). </P>
<P>下面的章节，解释EJB Descriptor，AspectJ，xDoclet等工具如何解决Separation of Aspects的问题。 </P>
<P>3．EJB Descriptor<BR>如果我们使用EJB实现上面的例子，Bank类可以作为一个Stateless Session Bean实现。 </P>
<P>在Bank的代码中只用考虑商业逻辑，不用考虑认证和事务等方面。 </P>
<P>认证和事务等方面在EJB Descriptor中定义，由EJB Container提供这些方面的实现。 </P>
<P>我们来看一下，如何使用EJB Descriptor描述上面的例子。 </P>
<P>EJB Descriptor包括一个ejb-jar.xml文件。ejb-jar.xml文件包含两大部分，enterprise-beans和assembly-descriptor部分。enterprise-beans部分包含EJB的定义--JNDI Name，EJB Home, Interface, Bean Class Path等；assembly-descriptor部分包括配置信息的定义--安全角色，事务控制等等。 </P>
<P>下面给出上面例子对应的模拟EJB Descriptor。 </P>
<P><BR>&lt;ejb-jar&gt;<BR>&lt;enterprise-beans&gt;<BR>&nbsp; &lt;session&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;ejb-name&gt;Bank&lt;/ejb-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; …<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;ejb-class&gt;example.Bank&lt;/ejb-class&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;session-type&gt;Stateless&lt;/session-type&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;transaction-type&gt;Container&lt;/transaction-type&gt;<BR>&lt;security-role-ref&gt;<BR>&lt;role-name&gt;bank-account&lt;/role-name&gt;<BR>&lt;/security-role-ref&gt;<BR>&nbsp; &lt;/session&gt;<BR>&lt;/enterprise-beans&gt;</P>
<P>&lt;assembly-descriptor&gt;<BR>&nbsp; &lt;security-role&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;role-name&gt;bank-account&lt;/role-name&gt;<BR>&nbsp; &lt;/security-role&gt;</P>
<P>&lt;method-permission&gt;<BR>&lt;role-name&gt;employee&lt;/role-name&gt;<BR>&lt;method&gt;<BR>&lt;ejb-name&gt;Bank&lt;/ejb-name&gt;<BR>&lt;method-name&gt;deposit&lt;/method-name&gt;<BR>&lt;/method&gt;<BR>&lt;method&gt;<BR>&lt;ejb-name&gt;Bank&lt;/ejb-name&gt;<BR>&lt;method-name&gt;withdraw&lt;/method-name&gt;<BR>&lt;/method&gt;<BR>&lt;/method-permission&gt;</P>
<P>&lt;container-transaction&gt;<BR>&lt;method&gt;<BR>&lt;ejb-name&gt;Bank&lt;/ejb-name&gt;<BR>&lt;method-name&gt;deposit&lt;/method-name&gt;<BR>&lt;/method&gt;<BR>&lt;method&gt;<BR>&lt;ejb-name&gt;Bank&lt;/ejb-name&gt;<BR>&lt;method-name&gt;withdraw&lt;/method-name&gt;<BR>&lt;/method&gt;</P>
<P>&lt;trans-attribute&gt;Required&lt;/trans-attribute&gt;<BR>&lt;/container-transaction&gt;<BR>&lt;/assembly-descriptor&gt;<BR>&lt;/ejb-jar&gt;</P>
<P>&nbsp;</P>
<P>本文后面会讲到如何用AspectJ实现上例中的Separation of Aspects。 </P>
<P>读者可以比较一下AspectJ语法和EJB Descriptor定义之间的对应关系。 </P>
<P>两者都提供了类名、方法名的匹配规则，能够把类的方法映射到认证，事务等Aspect（方面）。 </P>
<P>4．AspectJ<BR>这一节我们来看看AspectJ如何实现上例中的Separation of Aspects。 </P>
<P>使用AspectJ，我们不用对原有的代码做任何修改，就可以为代码提供不同的Aspect（方面）--比如，认证，事务等。 </P>
<P>我们只需要提供两个不同的Aspect--认证Aspect和事务Aspect。 </P>
<P><BR>Code 4.1 AuthAspect.java<BR>aspect AuthAspect{<BR>&nbsp; pointcut bankMethods() : execution (* Bank.deposit(…)) || execution (* Bank. withdraw (…));</P>
<P>&nbsp; Object around(): bankMethods(){<BR>&nbsp; // 验证account是否为合法用户</P>
<P>&nbsp; return proceed();<BR>&nbsp; }<BR>};</P>
<P>Code 4.2 TransactionAspect.java<BR>aspect TransactionAspect{<BR>&nbsp; pointcut bankMethods() : execution(* Bank.deposit(…)) || execution (* Bank. withdraw (…));</P>
<P>&nbsp; Object around(): bankMethods(){<BR>&nbsp; // Begin Transaction<BR>&nbsp; Object result = proceed();<BR>&nbsp; // End Transaction<BR>&nbsp; return result;<BR>&nbsp; }<BR>};</P>
<P>&nbsp;</P>
<P>如果您暂时不能理解这段代码，没有关系，后面会讲到，这些aspect的定义，不过是定义了一些代码生成规则。 </P>
<P>我们用AspectJ编译器编译Bank文件和含有aspect的这个文件，出来的结果就是带有安全认证和事务处理的Bank类。编译出来的这个Bank类调用了AspectJ Runtime Lib，所以，如果你要运行这个Bank类，你需要把AspectJ Runtime Lib设置在你的classpath里面。 </P>
<P>我们来看看，AspectJ编译器为我们做了什么事情。 </P>
<P>首先，AspectJ从文件列表里取出所有的文件名，然后读取这些文件，进行分析。 <BR>AspectJ发现一些文件含有aspect的定义，在这个例子里，就是AuthAspect和TransactionAspect的定义；这些aspect就是代码生成规则。 <BR>AspectJ根据这些aspect代码生成规则，修改添加你的源代码。在这个例子里，就是修改添加Bank文件。 <BR>AspectJ读取AuthAspect的定义，发现了一个pointcut--bankMethods()；这个pointcut的定义是execution(* Bank.deposit(…)) || execution(* Bank. withdraw (…))，表示所有对Bank类的deposit和withdraw方法的执行点。 <BR>AspectJ继续读取AuthAspect的定义，发现了一个around()，这在AspectJ中叫做Advice，我不明白为什么叫这个名字，不过没关系，我们只要知道它是干什么的就行了。Advice允许你在某个类的方法的调用之前或调用之后，加入另外的代码。Code 4.1所示代码中的around()的" // 验证account是否为合法用户"部分，就是要加入的代码。这段代码要加在哪里呢？around()后面跟了一个pointcut--bankMethods()。根据这个pointcut，AspectJ会把这段代码加入到Bank.deposit和Bank.withdraw两个方法的执行之前。达到的效果就如同Code 2.2所示。 <BR>AspectJ读取TransactionAspect的定义，象第（4）步一样，发现了发现了一个pointcut--bankMethods()。 <BR>AspectJ继续读取AuthAspect的定义，发现了一个around()。这次AspectJ把"Begin Transaction"和"End Transaction"两段代码加在Bank.deposit和Bank. withdraw两个方法的执行前后。达到的效果就如同Code 2.3所示。 <BR>如何验证这一点？您可以到 <A href="http://www.eclipse.org/aspectj/">http://www.eclipse.org/aspectj/</A>下载安装AspectJ，编译里面的Sample，把编译结果反编译一下，就可以看到AspetJ自动生成的代码。 </P>
<P>我们看到，AspectJ是一种代码自动生成工具。你编写一段通用的代码，比如认证方面的代码，事务方面的代码，然后根据AspectJ语法定义一套代码生成规则（aspect定义），AspectJ就会帮助你自动把这段通用代码分布到对应的代码里面去，简单快捷，算无遗策。 </P>
<P>无独有偶，一个著名的编译器生成工具--Java Compiler Compiler (JavaCC)，也采用了非常相似的代码生成机制。JavaCC允许你在语法定义规则文件中，加入你自己的Java代码，用来处理读入的各种语法元素。 </P>
<P>AspectJ令你的代码更精简，结构更良好。AspectJ的好处，我就不多说了，网上很多精彩的文章探讨AspectJ的各种用途。 </P>
<P>下面介绍一个著名的代码自动生成器--xDoclet，和EJB Descriptor，AspectJ之间的联系和比较。 </P>
<P>5．xDoclet<BR>我们知道，Doclet用来生成Javadoc，xDoclet是Doclet的扩展，不仅仅能生成Javadoc，还能够生成源代码和配置信息等。 </P>
<P>Doclet和xDoclet的工作原理，就是处理源代码中的注释中的tag，生成相应的信息。这些tag都以@开头，你可以自己定义tag和对tag的处理，生成自定义的信息。 </P>
<P>（这里提一下Apache Maven Project。Maven是一种Project Build工具。用Maven进行管理的项目，能够同时生成Javadoc和XRef。XRef是Source Code Cross Reference。) </P>
<P>JBoss就利用xDoclet为EJB自动生成EJB Home和EJB Object Interface源文件，和EJB Descriptor文件。 </P>
<P>在Sourceforge.net上看到一个叫做Barter的开源项目，利用xDoclet为类方法生成AspectJ代码。 </P>
<P>请注意，EJB Descriptor和AspectJ都是把方方面面的Aspects集中在一处进行管理，而xDoclet的思想是处理散布在源代码中的各种tag。 </P>
<P>xDoclet在生成EJB Descriptor和AspectJ等方面的应用，正应了中国的一句古话--分久必合，合久必分。 </P>
<P>6．总结<BR>开源项目的出现，打破了软件技术领域的众多壁垒，推动软件技术进程的日新月异。 </P>
<P>同时，一些新名词，新概念也层出不穷，令人眼花缭乱，无所适从。其实，很多东西都是换汤不换药，我们理解应用这些新技术的时候，要抓住本质，要破除迷信，破除任何人为的神秘感。 </P>
<P>举个例子，现在炒作的很热的一些概念，"Web Service"，还有"Grid Computation"（网格计算），都是基于原有的各种技术发展出来的。媒体和技术文章不应该人为地制造任何神秘感。 </P>
<P>互联网时代的权威，不是说出来的，而是做出来的。 </P>
<P>另外，围绕着一些有前途的新技术，总会出现大量的"快速入门手册"，有些简直就是对该技术帮助文档的翻译，而且，有难度的地方没有翻译出来，大家都明白的地方翻译得非常详尽，详尽到了没有必要的地步。这种因为市场需求而产生的应景时文，大量地出现在技术文章领域。 </P>
<P>笔者对本文的期望是，决不迷信，决不重复。并试图引入一种洁净的，毫无废话的文风。笔者期待一针见血的驳斥和批评。 </P>
<P>Enjoy it. J <BR>Thanks. </P>
<P>关于作者<BR>王海龙 普通程序员。 <BR>Powered by Open Source。致力于做一个Architect，Solution Provider，Best Practice Provider。 <BR>希望有一天，有足够的时间，精力和能力的时候，将把自己有限的一身所学的一点东西全部贡献给Open Source Project。 <BR>&nbsp;<BR></P><img src ="http://www.blogjava.net/lgcpeter/aggbug/11214.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lgcpeter/" target="_blank">freshboy</a> 2005-08-26 16:00 <a href="http://www.blogjava.net/lgcpeter/archive/2005/08/26/11214.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>