<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    最愛Java

    書山有路勤為徑,學海無涯苦作舟

    《AspectJ Cookbook》讀書筆記二十二: 應用企業(yè)級方面

    一. 應用開發(fā)指導和規(guī)則
            想通過提供一種在編譯時強制執(zhí)行的策略,來控制在應用程序中允許哪些程序構造。可使用Border Controller(邊界控制器)面向方面設計模式聲明代碼內的一組區(qū)域。當依據策略模式在方面中為項目聲明任何頂級規(guī)則時,重用這些區(qū)域。可以擴展項目的頂級策略,為應用程序的特定區(qū)域特殊化它們。
            示例中BorderControllerAspect聲明了4個區(qū)域:withinTestingRegion()區(qū)域納入了存放測試代碼的包,withinMyapp()指定了組成應用程序的包和子包,withinThirdParty()指定了可以使用第三方源代碼的任何區(qū)域,withinMyAppMainMethod()則方便地聲明了應用程序的main(..)方法的位置。
    package com.aspectj;

    public aspect BorderControllerAspect 
    {
       
    /**
        * Specifies the testing region. 
        
    */

       
    public pointcut withinTestingRegion() : within(com.oreilly.aspectjcookbook.testing.+);
       
       
    /**
        * Specifies My Applications region. 
        
    */

       
    public pointcut withinMyApp() : within(com.oreilly.aspectjcookbook.myapp.+);
       
       
    /**
        * Specifies a third party source code region.
        
    */

       
    public pointcut withinThirdParty() : within(com.oreilly.aspectjcookbook.thirdpartylibrary.+);
       
       
    /**
        * Specifies the applications main method.
        
    */

       
    public pointcut withinMyAppMainMethod() : withincode(public void com.oreilly.aspectjcookbook.myapp.MyClass.main(..));
    }


            示例中只顯示了可以在應用程序中定義的其中一些區(qū)域,其他良好的候選有:將發(fā)生特殊日志據記錄的區(qū)域;受延遲加載邏輯支配的區(qū)域;以及你發(fā)現(xiàn)體系結構的真實定界部分是有用的任何區(qū)域,他們使得更多的切入點定義可以重用,并在那些邊界內安全地工作。其思想是:如果這些邊界發(fā)生變化,則只需要更改Boarder Controller,使得應用程序其余切入點邏輯將立即獲得對其作用域的任何相關的改變。
            Border Controller提供了一個有用的可重用切入點定義的庫,它被納入到策略面向方面設計模式中。
    package com.aspectj;

    public abstract aspect ProjectPolicyAspect 
    {
       
    protected abstract pointcut allowedSystemOuts();
      
        declare warning : 
           call(
    * *.println(..)) && 
           
    !allowedSystemOuts() && 
           
    !BorderControllerAspect.withinTestingRegion()
        : 
    "System.out usage detected. Suggest using logging?";
    }
            為應用程序區(qū)域的細節(jié)特殊化項目級策略
    package com.aspectj;

    public aspect MyAppPolicyAspect extends ProjectPolicyAspect
    {
       
    /**
        * Specifies regions within the application where system out 
        * messages are allowed.
        
    */

       
    protected pointcut allowedSystemOuts() : 
          BorderControllerAspect.withinMyAppMainMethod() 
    || 
          BorderControllerAspect.withinThirdParty() 
    || 
          BorderControllerAspect.withinTestingRegion();
    }

    二.應用事務
    package com.aspectj;

    public abstract aspect TransactionAspect 
    {
       
    protected abstract pointcut transactionalCall();
       
       
    protected interface Transaction
       
    {
          
    public void commit();
          
    public void rollback();
       }

       
       
    protected pointcut transactionBoundary() : 
          transactionalCall() 
    && !cflowbelow(transactionalCall());
       
       before() : transactionBoundary() 
       

          setupTransaction(thisJoinPoint.getArgs());
       }

       
       after() returning: transactionBoundary() 
       

          transaction.commit();
       }

       
       after() throwing: transactionBoundary() 
       

          transaction.rollback();  
       }

       
       
    protected abstract void setupTransaction(Object[] args);
       
       
    protected Transaction transaction;
    }


            TransactionAspect首先指定transactionCall()抽象切入點。特殊化的子方面使用這個切入點來指定將把目標應用程序內的方法視作事務性的。
            transactionBounday()切入點然后依靠transactionCall()切入點來指定事務開始和結束的位置。cflowbelow()切入點用于忽略可能出現(xiàn)在事務壽命內的任何連接點。
            TransactionAspect()一般需要存儲事務并與之交互,因此定義了Transaction接口。Transaction接口為子方面提供了一個基礎,用以實現(xiàn)他們自己的事務類。然后使用單個事務屬性來指定正被方面管理的當前事務。
    最后,在事務生命周期內的不同時刻,將有三份通知處理事務屬性。before()通知調用setupTransaction(Object[])抽象方法,以便用合適的Transaction實現(xiàn)正確地初始化事務屬性。如果transactionCall()切入點所選的連接點未引發(fā)異常地返回,將會執(zhí)行after() returning通知;這是提交事務的良好時間。after() throwing通知用于連接點帶異常地返回的情況,因此需要回滾事務。
    package com.aspectj;

    public aspect TransferTransactionAspect extends TransactionAspect 
    {
       
    protected pointcut transactionalCall() : 
          call(
    public void com.oreilly.aspectjcookbook.Bank.transfer(..));
       
       
    private class TransferTransaction extends ThreadLocal implements Transaction
       
    {
          
    private Account from;
          
    private Account to;
          
    private float value;
          
          
    public TransferTransaction(Account from, Account to, float value)
          
    {
             
    this.from = from;
             
    this.to = to;
             
    this.value = value;
          }

          
          
    public void commit()
          
    {
             System.out.println(
    "Committing");
             
    // Nothing to actually commit here, all the changes have been accepted ok
          }

          
          
    public void rollback()
          
    {
             System.out.println(
    "Rolling back");
             
    try
             
    {
                to.debit(value);
             }

             
    catch(InsufficientFundsException ife)
             
    {
                System.err.println(
    "Could not complete rollback!");
                ife.printStackTrace();
             }

          }

       }

       
       
    protected void setupTransaction(Object[] args)
       
    {
          
    this.transaction = 
             
    new TransferTransaction(
                   (Account) args[
    0], 
                   (Account) args[
    1], 
                   ((Float)args[
    2]).floatValue());
       }

    }


    三.應用資源池
    package com.aspectj;

    import java.util.WeakHashMap;

    public abstract aspect ResourcePoolingAspect 
    {  
       
    public interface Resource
       
    {
          
       }

       
       
    public interface ResourcePool
       
    {
          
    public void add(Resource resource);
          
    public Resource remove();
       }

       
       
    protected class ResourcePoolsCollection
       
    {
          WeakHashMap pools 
    = new WeakHashMap();
          
          
    public void putResourcePool(ResourcePool pool, Class resourceClass)
          
    {
             pools.put(resourceClass, pool);
          }

          
          
    public ResourcePool getResourcePool(Class resourceClass)
          
    {
             
    return (ResourcePool) pools.get(resourceClass);
          }

       }

       
       
    protected ResourcePoolsCollection resourcePools = new ResourcePoolsCollection();
       
       
    public ResourcePoolingAspect()
       
    {  
          initializeSpecificPool();
       }

       
       
    protected abstract void initializeSpecificPool();
       
       
    private pointcut excludeAspects() : !within(ResourcePoolingAspect+);
       
       
    public abstract pointcut catchResourceConstruction();
       
       
    public abstract pointcut catchResourceDestruction(Resource resource);
       
       Object around() : catchResourceConstruction() 
    && excludeAspects()
       
    {
          ResourcePool resources 
    = 
             resourcePools.getResourcePool(thisJoinPoint.getSignature().getDeclaringType());
          
    return resources.remove();
       }

       
       Object around(Resource resource) : catchResourceDestruction(resource) 
    && excludeAspects()
       
    {
          ResourcePool resources 
    = 
             resourcePools.getResourcePool(thisJoinPoint.getSignature().getDeclaringType());
          Object returnValue 
    = resourceReturnedToPool(resource);
          System.out.println(
    "Resource added back into pool: " + resource);
          resources.add(resource);
          
    return returnValue;
       }

       
       
    protected abstract Object resourceReturnedToPool(Resource resource);
       
    }


            示例中定義了一個可重用的抽象方面,它將在最初不支持資源池的應用程序內提供一個資源池。聲明Resource和ResourcePool接口,以便可以對這些接口定義通用的資源池行為,并把它們與這些接口可能的實現(xiàn)方式隔離開。
            可以跨所有聲明為子方面的資源池共享在抽象的ResourcePoolingAspect內聲明的行為。ResourcePoolCollection類為整個應用程序中的所有資源池提供了一個公共庫,使得通用代碼可以依據特定資源池說包含資源的類,來查尋該資源池。
    package com.aspectj;

    import java.util.List;
    import java.util.ArrayList;

    public aspect BusinessResourcePoolingAspect extends ResourcePoolingAspect
    {
       declare parents : BusinessResource 
    implements Resource;

       
    public pointcut catchResourceConstruction() : call(public BusinessResource.new());
       
       
    public pointcut catchResourceDestruction(Resource resource) : 
          call(
    public void BusinessResource.close()) && target(resource);

       
    private class BusinessResourcePool implements ResourcePool
       
    {
          
    private static final int RESOURCE_POOL_SIZE = 10;
          
          List resources 
    = new ArrayList();
          
          
    public BusinessResourcePool()
          
    {
             
    for (int x = 0; x < RESOURCE_POOL_SIZE; x++)
             
    {
                
    this.add(new BusinessResource());
             }

          }

          
          
    public synchronized void add(Resource resource)
          
    {
             resources.add(resource);
          }

          
          
    public synchronized Resource remove()
          
    {
             
    if (resources.size() == 0)
             
    {
                resources.add(
    new BusinessResource());
             }

             
    return (Resource) resources.remove(resources.size() - 1);
          }

       }

       
       
    protected void initializeSpecificPool()
       
    {
          
    try
          
    {
             
    this.resourcePools.putResourcePool(new BusinessResourcePool(), 
                   Class.forName(
    "com.oreilly.aspectjcookbook.BusinessResource"));
          }

          
    catch (ClassNotFoundException cnfe)
          
    {
             System.err.println(
    "Couldn't find resource class to pool");
          }

             
       }

       
       
    protected Object resourceReturnedToPool(Resource resource)
       
    {
          
    // Do any resource specific tudying up if necessary
          
    // None to do in this example
          return null;
       }

    }


    四.使用RMI透明地遠程訪問類
        創(chuàng)建一個RMI服務器應用程序,它包含類的一個實例。如:
    import java.rmi.RemoteException;
    import java.rmi.server.*;

    public class ThisOrThatServerImpl extends UnicastRemoteObject implements ThisOrThatServer
    {
        BusinessClass businessClass 
    = new BusinessClass();
        
       
    public ThisOrThatServerImpl() throws RemoteException
       
    {
          
       }

       
       
    public void foo() throws RemoteException
       
    {
          
    this.businessClass.foo();
       }

    }

            在客戶應用程序內創(chuàng)建一個方面,它用于截獲對遠程類的特定實例的調用,并把這些調用路由到相應的RMI服務器,如:

    import java.rmi.*;

    public aspect RemoteBusinessClassAspect 
    {
       
    public pointcut callBusinessClassFooInMain() : call(public void BusinessClass.foo()) &&
       withincode(
    public void MainApplication.main(String[]));
       
       
    void around() : callBusinessClassFooInMain()
       
    {
          
    try
          
    {
             ThisOrThatServer rmtServer 
    = (ThisOrThatServer) Naming.lookup("rmi://localhost/TTTServer");
             rmtServer.foo();
          }

          
    catch (Exception e)
          
    {
             System.err.println(
    "Problems occured when attempting " +
             
    "to use remote object, default to local");
             proceed();
          }

       }

    }

    五.應用安全策略
     
    package com.aspectj;


    public aspect SecureClassAAspect 
    {
       
    private boolean authenticated;
       
       
    public pointcut secureClassAMethods() : 
          call(
    * com.oreilly.aspectjcookbook.ClassA.*(..));
          
       Object around() : secureClassAMethods()
       
    {
          
    if (authenticated)
          
    {
             
    return proceed();
          }

          
    else
          
    {
             LoginScreen loginScreen 
    = new LoginScreen();
             loginScreen.setVisible(
    true);
             
             
    // Use the authentication procedure of your choice here
             
    // In this simple example we are just going to check that 
             
    // it is the one person we know of
             if ((loginScreen.getUsername().equals("Richard")) && 
                   (
    new String(loginScreen.getPassword()).equals("password")))
             
    {
                authenticated 
    = true;
                loginScreen.dispose();
                
    return proceed();
             }

             loginScreen.dispose();
             
    return null;
          }

       }

    }

    posted on 2008-08-29 15:47 Brian 閱讀(290) 評論(0)  編輯  收藏 所屬分類: 《AspectJ Cookbook》讀書筆記

    公告


    導航

    <2008年8月>
    272829303112
    3456789
    10111213141516
    17181920212223
    24252627282930
    31123456

    統(tǒng)計

    常用鏈接

    留言簿(4)

    隨筆分類

    隨筆檔案

    收藏夾

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 99久热只有精品视频免费观看17| 亚洲AV无码一区二区二三区入口| 无码人妻久久一区二区三区免费| 国产99久久亚洲综合精品| 中文字幕在线观看亚洲| 亚洲综合色成在线播放| 日本免费网站观看| 免费H网站在线观看的| 98精品全国免费观看视频| 国产精品免费观看视频| 免费无码AV一区二区| 国产精品无码亚洲精品2021 | 理论亚洲区美一区二区三区| 亚洲综合无码一区二区三区| 亚洲熟女少妇一区二区| 亚洲国产人成精品| 免费a级毛片无码av| 色视频色露露永久免费观看| 在人线av无码免费高潮喷水| 成人免费视频网站www| 51在线视频免费观看视频| 四虎影视在线影院在线观看免费视频| 国产日韩在线视频免费播放| 乱爱性全过程免费视频| 免费无码午夜福利片| 免费一级毛片在线播放视频免费观看永久 | 99精品全国免费观看视频| 免费人成在线观看69式小视频| 久久精品中文字幕免费| 日韩电影免费在线观看网站| 岛国岛国免费V片在线观看| 中文字幕在线免费播放| 成人无码精品1区2区3区免费看| 成人免费ā片在线观看| 中文日本免费高清| 国产一级片免费看| 97精品免费视频| 美女视频黄免费亚洲| 成人av免费电影| 国产免费变态视频网址网站| 免费a级毛片网站|