乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      AOP下的權(quán)限控制實(shí)現(xiàn)

       鳳舞天煌 2007-07-24

      AOP下的權(quán)限控制實(shí)現(xiàn)

      2006-07-10 05:00 作者: 陳景燕 陽(yáng)國(guó)貴 出處: 計(jì)算機(jī)與信息技術(shù) 責(zé)任編輯:方舟
       
        摘要 面向方面的編程(AOP)是一種新的編程技術(shù),它彌補(bǔ)了面向?qū)ο蟮木幊?OOP)在跨越模塊行為上的不足。AOP引進(jìn)了Aspect,它將影響多個(gè)類(lèi)的行為封裝到一個(gè)可重用模塊中,它允許程序員對(duì)橫切關(guān)注點(diǎn)進(jìn)行模塊化,從而消除了OOP引起的代碼混亂和分散問(wèn)題,增強(qiáng)了系統(tǒng)的可維護(hù)性和代碼的重用性。本文分析傳統(tǒng)權(quán)限控制的實(shí)現(xiàn)方法,并研究了在AOP下權(quán)限控制的實(shí)現(xiàn)方法。

        關(guān)鍵詞 AOP;橫切關(guān)注點(diǎn); 設(shè)計(jì)模式; 權(quán)限控制

        OOP應(yīng)用開(kāi)發(fā)面臨的問(wèn)題

        面向?qū)ο蠹夹g(shù)很好地解決了軟件系統(tǒng)中角色劃分的問(wèn)題。借助于面向?qū)ο蟮姆治?、設(shè)計(jì)和實(shí)現(xiàn)技術(shù),開(kāi)發(fā)者可以將問(wèn)題領(lǐng)域的“名詞”轉(zhuǎn)換成軟件系統(tǒng)中的對(duì)象,從而很自然地完成從問(wèn)題到軟件的轉(zhuǎn)換。

        但是,問(wèn)題領(lǐng)域的某些需求卻偏偏不是用這樣的“名詞”來(lái)描述的。比如遇到這樣的問(wèn)題:需要對(duì)系統(tǒng)中的某些方法進(jìn)行權(quán)限檢驗(yàn),這種需要權(quán)限檢驗(yàn)的方法散布在40多個(gè)類(lèi)中。面對(duì)這種需求,應(yīng)該怎么辦呢?最直接的辦法就是:創(chuàng)建一個(gè)起類(lèi)(或接口),將權(quán)限檢驗(yàn)的功能放在其中,并讓所有需要權(quán)限檢驗(yàn)的類(lèi)繼承這個(gè)起類(lèi)(或接口).如果這個(gè)需求是后期提出的.需要修改的地方就會(huì)分散在40多個(gè)文件中。這樣大的修改量,無(wú)疑會(huì)增加出錯(cuò)的幾率,并且加大系統(tǒng)維護(hù)的難度。

        人們認(rèn)識(shí)到,傳統(tǒng)的程序經(jīng)常表現(xiàn)出一些不能自然地適合單個(gè)程序模塊或者幾個(gè)緊密相關(guān)的程序模塊的行為例如權(quán)限檢驗(yàn)、日志記錄、對(duì)上下文敏感的錯(cuò)誤處理、性能優(yōu)化以及設(shè)計(jì)模式等等、我們將這種行為稱(chēng)為“橫切關(guān)注點(diǎn)(crosscuttingconcern)”,因?yàn)樗缭搅私o定編程模型中的典型職責(zé)界限。如果使用過(guò)用于橫切關(guān)注點(diǎn)的代碼,您就會(huì)知道缺乏模塊性所帶來(lái)的問(wèn)題。因?yàn)闄M切行為的實(shí)現(xiàn)是分散的,開(kāi)發(fā)人員發(fā)現(xiàn)這種行為難以作邏輯思維、實(shí)現(xiàn)和更改。

        AOP的基本思想

        AOP是Aspect Oriented Programming的縮寫(xiě),意思是面向方面編程,一種新興的編程技術(shù)。AOP實(shí)際是GoF設(shè)計(jì)模式的延續(xù),設(shè)計(jì)模式孜孜不倦追求的是調(diào)用者和被調(diào)用者之間的解耦,AOP可以說(shuō)也是這種目標(biāo)的一種實(shí)現(xiàn)。它可以解決OOP和過(guò)程化方法不能夠很好解決的橫切(crosscut)問(wèn)題,如:事務(wù)、安全、日志等橫切關(guān)注。當(dāng)未來(lái)系統(tǒng)變得越來(lái)越復(fù)雜,橫切關(guān)注點(diǎn)就成為一個(gè)大問(wèn)題的時(shí)候,AOP就可以很輕松的解決橫切關(guān)注點(diǎn)這個(gè)問(wèn)題。


      圖 1 把模塊作為一批關(guān)注點(diǎn)來(lái)實(shí)現(xiàn)

        通常,為滿(mǎn)足整個(gè)企業(yè)應(yīng)用某方面得需求,開(kāi)發(fā)者(架構(gòu)師)需要整理出系統(tǒng)得關(guān)注點(diǎn)。圖 1形象地描述了關(guān)注點(diǎn),它能夠從AOP Aspect角度看待系統(tǒng)。比如,持久化、日志、應(yīng)用的業(yè)務(wù)邏輯通常被認(rèn)為是應(yīng)用需要解決的問(wèn)題。因此,他們通常作為關(guān)注點(diǎn)看待。從整個(gè)系統(tǒng)角度考慮,它往往是由大量的關(guān)注點(diǎn)構(gòu)成的。

        我們把AOP看作是OOP的延續(xù),而不是競(jìng)爭(zhēng)對(duì)手。OOP在通常的場(chǎng)合下工作得很好,但在特定的領(lǐng)域里卻有所欠缺:舉例來(lái)說(shuō),如果我們必須為多個(gè)對(duì)象和方法應(yīng)用相同的事務(wù)行為,我們需要將同樣的代碼剪切/粘貼到每一個(gè)方法里。AOP讓我們可以把這類(lèi)問(wèn)題封裝到方面(aspect)中,從而更好地實(shí)現(xiàn)模塊化。AOP定義了“切入點(diǎn)”(pointcut)的概念,讓開(kāi)發(fā)者可以從另一個(gè)角度來(lái)思考程序的結(jié)構(gòu),從而彌補(bǔ)了OOP的某些缺陷:如果需要對(duì)一組方法施加橫切的行為,就應(yīng)該攔截這些方法。

        在J2EE應(yīng)用開(kāi)發(fā)中,我們主要用到AOP的攔截(interception)能力,它為我們提供了“在任何對(duì)象的方法調(diào)用前/后加入自定義行為”的能力,這使得我們可以處理企業(yè)應(yīng)用中的橫切(crosscutting)關(guān)注點(diǎn)(即:同時(shí)作用于多個(gè)對(duì)象的關(guān)注點(diǎn)),并且仍然保持強(qiáng)類(lèi)型(不需要改變方法簽名)。

        權(quán)限控制的應(yīng)用程序?qū)崿F(xiàn)

        對(duì)于權(quán)限管理的做法,在WEB實(shí)現(xiàn)上,有以下幾種:

       ?、?利用Filter,對(duì)所有進(jìn)入的URI進(jìn)行解析,并取得當(dāng)時(shí)Session中的User信息,然后通過(guò)RBAC的機(jī)制,將此鏈接需要的權(quán)限與用戶(hù)擁有的權(quán)限進(jìn)行比較,然后進(jìn)行相應(yīng)的處理。這種做法有很多好處:簡(jiǎn)單,容易實(shí)現(xiàn),并且對(duì)系統(tǒng)侵入性也不強(qiáng)。這里URL就是RBAC中的資源了。這樣做的缺點(diǎn)是所有對(duì)數(shù)據(jù)的操作必須通過(guò)URL來(lái)體現(xiàn),這一點(diǎn)在現(xiàn)代的程序中不太好實(shí)現(xiàn)。如果采用Struts, XWork或者Tapestry,采用同一個(gè)URL(瀏覽器看來(lái))進(jìn)行處理多項(xiàng)任務(wù)已不是什么稀奇的事。

        ⑵ 利用一個(gè)BaseServlet(Servlet+Jsp經(jīng)典模式)或者BaseAction(Struts模式)或者BasePage(Tapestry模式)或者BaseController(SpringMVC模式),對(duì)所有的請(qǐng)求先進(jìn)行過(guò)濾進(jìn)行權(quán)限操作,然后再處理。稍微看一下就知道這種模式跟Filter并無(wú)本質(zhì)不同。優(yōu)缺點(diǎn)同上。

        那么,如果要實(shí)現(xiàn)更為細(xì)致的權(quán)限操作,精確到某個(gè)方法的權(quán)限,典型的做法如下:

      public someFunciton() {
       //權(quán)限判斷
       User user = context.getUser();
       if (user.canExecuteThisFunction()) {
        // do the business method
        // ...
       } else {
        throw new PermissionDeniedException();
       }
      }

        這種做法能夠?qū)?quán)限的粒度控制到具體的業(yè)務(wù)方法,因此它的控制能力應(yīng)該是強(qiáng)大的。可以看到,權(quán)限判斷部分對(duì)于每個(gè)方法幾乎是獨(dú)立的。

        這種在具體功能前加入權(quán)限操作檢驗(yàn)的實(shí)現(xiàn)方式有很多缺點(diǎn):

        ⑴ 每個(gè)功能類(lèi)都需要相應(yīng)的權(quán)限檢驗(yàn)代碼,將程序功能和權(quán)限檢驗(yàn)混淆在一起,存在緊密的耦合性,擴(kuò)展修改難度大。

        ⑵ 以代理模式為每個(gè)功能類(lèi)實(shí)現(xiàn)一個(gè)相應(yīng)的代理類(lèi),雖然解耦了程序功能和權(quán)限檢驗(yàn),但是,從某個(gè)角色的權(quán)限檢驗(yàn)這個(gè)切面考慮,涉及具體Proxy類(lèi)太多,擴(kuò)展修改難度大。

        權(quán)限控制的J2EE容器實(shí)現(xiàn)

        在AOP概念沒(méi)有誕生前,J2EE規(guī)范已經(jīng)提供了關(guān)于權(quán)限控制的容器實(shí)現(xiàn)標(biāo)準(zhǔn),這種變遷結(jié)果如下圖所示:


      圖2 權(quán)限控制的J2EE容器實(shí)現(xiàn)

        原來(lái)需要每個(gè)應(yīng)用程序?qū)崿F(xiàn)的權(quán)限Proxy轉(zhuǎn)為整個(gè)容器的Proxy實(shí)現(xiàn),其中JDK1.3以后的動(dòng)態(tài)代理API為這種轉(zhuǎn)換實(shí)現(xiàn)提供了技術(shù)保證。

        非常明顯,通過(guò)容器實(shí)現(xiàn)權(quán)限控制驗(yàn)證可以大大簡(jiǎn)化應(yīng)用程序的設(shè)計(jì),分離了應(yīng)用系統(tǒng)的權(quán)限關(guān)注,將權(quán)限控制變成了對(duì)J2EE容器服務(wù)器的配置工作。

        其實(shí),容器的權(quán)限實(shí)現(xiàn)也是一種從一個(gè)側(cè)面來(lái)解決問(wèn)題方式,AOP概念誕生后,權(quán)限控制實(shí)現(xiàn)由此也帶來(lái)了兩個(gè)方向的變化:

       ?、拧2EE容器級(jí)別的權(quán)限實(shí)現(xiàn),也就是容器自身的權(quán)限實(shí)現(xiàn)。

       ?、啤2EE應(yīng)用程序級(jí)別的權(quán)限實(shí)現(xiàn)。

        權(quán)限控制在容器級(jí)別實(shí)現(xiàn)似乎使得J2EE開(kāi)發(fā)者感覺(jué)沒(méi)有靈活性和可擴(kuò)展性,其實(shí)象JBoss 4.0這樣的J2EE容器,由于引入了AOP概念,使得J2EE開(kāi)發(fā)者在自己的應(yīng)用系統(tǒng)中能夠直接操縱容器的一些行為。容器和應(yīng)用系統(tǒng)由于AOP引入的Aspect切面,變得可以成為一體了。

        對(duì)于J2EE應(yīng)用系統(tǒng)開(kāi)發(fā)者,能夠做到上述境界,必須的條件是對(duì)JBoss之類(lèi)J2EE容器必須有足夠的了解,因?yàn)檫@些方式并不是J2EE標(biāo)準(zhǔn),有可能在移植到新的J2EE容器,這些知識(shí)和投入變得無(wú)用(也有可能將來(lái)J2EE擴(kuò)展其標(biāo)準(zhǔn))。

        很顯然,使用AOP實(shí)現(xiàn)J2EE應(yīng)用系統(tǒng)級(jí)別的權(quán)限控制,是解決上述移植風(fēng)險(xiǎn)的一個(gè)主要方法,但是帶來(lái)的缺點(diǎn)是必須親自從零開(kāi)始做起,耗費(fèi)時(shí)間不會(huì)很短。

        AOP下的權(quán)限控制實(shí)現(xiàn)

        有了AOP,新的業(yè)務(wù)方法可以這樣寫(xiě):

      public someFunciton() {
       // do the business method
       // ...
      }

        沒(méi)有了額外的權(quán)限操作,這個(gè)業(yè)務(wù)方法看起來(lái)那么清晰自然。

        將對(duì)權(quán)限的操作作為一個(gè)Advice,并將Advisor關(guān)注到所有的業(yè)務(wù)方法(可能有某一個(gè)特定package),然后,剩下的事情就由RBAC以及AOP來(lái)完成了。通過(guò)這樣的分離,縱向的一個(gè)業(yè)務(wù)方法被分割為一個(gè)更為自然的業(yè)務(wù)方法和一個(gè)關(guān)注點(diǎn)。這個(gè)關(guān)注點(diǎn)寫(xiě)法可能如下:

      public class PermissionCheckAdvice implements MethodBeforeAdvice {
       public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
        //權(quán)限判斷
        if (!this.getContext().getUser().canExcute(this, arg0)) {
         throws new PermissionDeniedException();
        }
       }
      }

        可能有個(gè)問(wèn)題:如何取得context或者當(dāng)時(shí)上下文環(huán)境的User呢?答案是使用IoC(或稱(chēng)Dependency Injection),將上下文環(huán)境或者User作為參數(shù)反向傳入到邏輯方法中。當(dāng)然,在傳入之前,這些變量是需要初始化的。這個(gè)初始化工作可以在SuperServlet中進(jìn)行,并且以Session單例的形式保存在應(yīng)用程序中。下面是Spring配置文件的例子:

      <beans>
      <!-- Bean configuration -->
      <bean id="businesslogicbean"
      class="org.springframework.aop.framework.ProxyFactoryBean">
      <property name="proxyInterfaces">
      <value>IBusinessLogic</value>
      </property>
      <property name="target">
      <ref local="beanTarget"/>
      </property>
      <property name="interceptorNames">
      <list>
      <value>thePermissionCheckBeforeAdvisor</value>
      </list>
      </property>
      </bean>
      <!-- Bean Classes -->
      <bean id="beanTarget" class="BusinessLogic">
      <property name="user"><<YOUR USER OBJECT>> </property>
      </bean>
      <!-- Advisor pointcut definition for before advice -->
      <bean id="thePermissionCheckBeforeAdvisor"
      class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
      <property name="advice">
      <ref local="thePermissionCheckBeforeAdvice"/>
      </property>
      <property name="pattern">
      <value>.*</value>
      </property>
      </bean>
      <!-- Advice classes -->
      <bean id="thePermissionCheckBeforeAdvice"
      class="PermissionCheckBeforeAdvice"/>
      </beans>

        結(jié)束語(yǔ)

        AOP引進(jìn)了Aspect,它將影響多個(gè)類(lèi)的行為封裝到一個(gè)可重用模塊中,它允許程序員對(duì)橫切關(guān)注點(diǎn)進(jìn)行模塊化,從而消除了OOP引起的代碼混亂和分散問(wèn)題,增強(qiáng)了系統(tǒng)的可維護(hù)性和代碼的重用性。利用AOP的攔截(interception)能力,它為我們提供了“在任何對(duì)象的方法調(diào)用前/后加入自定義行為”的能力,這使得我們可以處理企業(yè)應(yīng)用中的權(quán)限控制這一橫切關(guān)注點(diǎn),并且仍然保持強(qiáng)類(lèi)型(不需要改變方法簽名),解耦了程序功能和權(quán)限檢驗(yàn)。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多