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

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

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

    最?lèi)?ài)Java

    書(shū)山有路勤為徑,學(xué)海無(wú)涯苦作舟

         摘要: 一. 捕獲方法調(diào)用         使用call(Signature)切入點(diǎn)。其語(yǔ)法:          pointcut <pointcut name>(<any values to be picked u...  閱讀全文
    posted @ 2008-07-03 22:17 Brian 閱讀(1519) | 評(píng)論 (2)編輯 收藏
    一. 安裝AspectJ
            從最簡(jiǎn)單的方面來(lái)說(shuō),AspectJ安裝很簡(jiǎn)單:
             1.從http://www.aspectj.org下載最新版本(目前版本是1.6.0)。
             2.通過(guò)雙擊下載下來(lái)的JAR來(lái)安裝。其默認(rèn)安裝目錄為asprctj1.6目錄。
             3.可在安裝目錄的bin目錄下調(diào)用ajc命令查看幫助。
             4.使用AspectJ只需復(fù)制aspectjrt.jar即可。

    二. 第一個(gè)簡(jiǎn)單的方面
            
    簡(jiǎn)單的業(yè)務(wù)邏輯Java類(lèi)
    package com.oreilly.aspectjcookbook;

    public class MyClass {
        
    public void foo(int number , String name) {
            System.out.println(
    "Inside foo(int , String)");
        }

        
        
    public static void main(String[] args) {
            
    //Create an instance of MyClass
            MyClass myObject = new MyClass();
            
    //Make the call to foo
            myObject.foo(1 , "Russ Miles");
        }

    }

            AspectJ的簡(jiǎn)單的HelloWorld方面
    package com.oreilly.aspectjcookbook;

    public aspect HelloWorld {
        pointcut callPointcut() :
            call(
    void com.oreilly.aspectjcookbook.MyClass.foo(int,String));
        
        
        before() : callPointcut() 
    {
            System.out.println(
    "Hello World");
            System.out.println(
    "In the advice attached to the call pointcut");
        }

    }

    將上述兩個(gè)文件保存在同一目錄中,運(yùn)行ajc命令,編譯這兩個(gè)文件,并產(chǎn)生方面和類(lèi)的.class文件。
            ajc -classpath %MY_CLASSPATH% -d %MY_DESTINATION_DIRECTORY% com/oreilly/aspectjcookbook/MyClass.java com/oreilly/aspectjcookbook/HelloWorld.java
    在使用上述命令過(guò)程中,需要確保aspectjrt.jar在你的類(lèi)路徑中。
    ajc編譯器會(huì)將產(chǎn)生兩個(gè).class文件:MyClass.class和HelloWorld.class。并可通過(guò)正常的java命令來(lái)運(yùn)行:
            java -classpath %MY_CLASSPATH% com.oreilly.aspectjcookbook.MyClass
    可得到如下結(jié)果:
            Hello World
            In the advice attached to the call pointcut  
            Inside foo(int , String)
    是不是很簡(jiǎn)單呢?現(xiàn)在我們來(lái)分析一下方面的每一行的含義:
     1package com.oreilly.aspectjcookbook;
     2
     3public aspect HelloWorld {
     4    pointcut callPointcut() :
     5        call(void com.oreilly.aspectjcookbook.MyClass.foo(int,String));
     6    
     7    
     8    before() : callPointcut() {
     9        System.out.println("Hello World");
    10        System.out.println("In the advice attached to the call pointcut");
    11    }

    12}


     第3行聲明了一個(gè)方法。
     第4行和第5行聲明單一命名的切入點(diǎn)的邏輯。切入點(diǎn)邏輯指定了應(yīng)用程序中的任何連接點(diǎn),本例中會(huì)捕獲對(duì)void com.oreilly.aspectjcookbook.MyClass.foo(int,String)方法的調(diào)用。切入點(diǎn)被命名為callPointcut(),使得可以在方面的作用域內(nèi)的任意位置都可以引用它。
     第8行到11行聲明單一通知塊。before()通知只是簡(jiǎn)單地指出它將在任何被callPointcut()切入點(diǎn)匹配的連接點(diǎn)之前執(zhí)行。
    注意:除了.java可作為后綴名以外,.aj也可以作為后綴名使用。ajc工具都會(huì)編譯所提供的文件。兩者沒(méi)有區(qū)別,只是個(gè)人喜好而已。

    三. 編譯一個(gè)方面和多個(gè)Java文件
        
    如果需要多個(gè)文件,那么按上述方法編譯是一件痛苦的事情。好在我們可以編寫(xiě)一個(gè)AspectJ配置構(gòu)建文件。配置構(gòu)建文件的后綴名為.lst,其中包含了所有在編譯中需要使用的類(lèi)文件和方面的名稱(chēng)。如:
            //File in file.lst
            com/oreilly/aspectjcookbook/MyClass.java
            com/oreilly/aspectjcookbook/MyAspect.java
            com/oreilly/aspectjcookbook/AnotherClass.java
            com/oreilly/aspectjcookbook/AnotherAspect.java
    然后使用如下命令編譯:
            ajc -argfile file.lst -classpath %MY_CLASSPATH% -d %MY_DESTINATION_DIRECTORY%

    四. 織入方面到j(luò)ar中
        1.首先編譯MyClass.java并打包到MyApp.jar中
            java -classpath %MY_CLASSPATH% -d %MY_DESTINATION_DIRECTORY% com/oreilly/aspectjcookbook/MyClass.java
            jar -cvf MyApp.jar com/oreilly/aspectjcookbook/MyClass.class
        2.ajc -classpath %MY_CLASSPATH% -d %MY_DESTINATION_DIRECTORY% -inpath MyApp.jar com/oreilly/aspectjcookbook/HelloWorld.java
            -inpath選項(xiàng)強(qiáng)制ajc編譯器從提供的.jar文件中把Java字節(jié)碼提取到-d選項(xiàng)所指定的目錄中。然后,ajc編譯器將把字節(jié)碼在方面織入過(guò)程中。
        3. 上述命令并不會(huì)產(chǎn)生新的.jar包,如需要將方面織入到新的包中,則需要使用-ourjar選項(xiàng):
            ajc -classpath %MY_CLASSPATH% -d %MY_DESTINATION_DIRECTORY% -inpath MyApp.jar -outjar MyAspectOriente的App.jar com/oreilly/aspectjcookbook/HelloWorld.java

    五.其他
      aj命令可以加載時(shí)織入方面
      ajdoc則可生成Javadoc文檔

    六. 使用Ant構(gòu)建一個(gè)AspectJ項(xiàng)目

    <?xml version="1.0" encoding="utf-8"?>
    <project basedir="." default="compile" name="test">
        
    <property name="src" value="src"/>
        
    <property name="build" value="build"/>
        
    <taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties">
            
    <classpath>
                
    <pathelement location="%ASPECTJ_INSTALLATION%/lib/aspectjtools.jar"/>
            
    </classpath>
        
    </taskdef>
        
    <target name="compile">
            
    <mkdir dir="${build}"/>
            
    <iajc destdir="${build}" sourceroots="${src}">
                
    <classpath>
                    
    <pathelement location="%ASPECTJ_INSTALLATION%/lib/aspectjrt.jar"/>
                
    </classpath>
            
    </iajc>
        
    </target>
    </project>

        上述代碼所做的工作:
          1. 使用AspectJ任務(wù)屬性定義了一個(gè)新的任務(wù)
          2. 指定aspectjtools.jar的位置
          3. 聲明一個(gè)構(gòu)建目標(biāo),他使用iajc任務(wù)來(lái)編譯項(xiàng)目,這個(gè)任務(wù)反過(guò)來(lái)又依賴(lài)于aspectjrt.jarlai
    posted @ 2008-06-30 23:10 Brian 閱讀(853) | 評(píng)論 (0)編輯 收藏

    橫切關(guān)注點(diǎn)
            面向?qū)ο缶幊痰幕厩疤峋褪亲岄_(kāi)發(fā)人員能夠在軟件中表述模塊化的橫切關(guān)注點(diǎn)(crosscutting concern)。橫切關(guān)注點(diǎn)是跨軟件特定部分使用的一種行為,通常也是一種數(shù)據(jù)。它可能是一種約束,作為軟件本身的一種特征,或者只是所有類(lèi)都必須執(zhí)行的一種行為。

    方面
            方面(aspect)是橫切關(guān)注點(diǎn)的另一種稱(chēng)呼。方面提供了一種機(jī)制,利用該機(jī)制,可以用一種模塊化的方式指定橫切關(guān)注點(diǎn)。為了充分利用方面的威力,我們需要了解一些基本概念,以便用一般的方式指定和應(yīng)用方面。我們必須能夠:
            以模塊化的方式定義方面
            動(dòng)態(tài)地應(yīng)用方面
            根據(jù)一組規(guī)則應(yīng)用方面
            根據(jù)一種機(jī)制和一種環(huán)境,用于指定將為特定方面執(zhí)行的代碼
            面向方面方法提供了一組語(yǔ)義和語(yǔ)法構(gòu)造來(lái)滿(mǎn)足這些要求,使得無(wú)論編寫(xiě)的是哪一類(lèi)軟件,都可以一般地應(yīng)用方面。這些構(gòu)造就是通知(advice)、連接點(diǎn)(join point)和切入點(diǎn)(pointcut)。

     通知
            通知就是方面被調(diào)用時(shí)所執(zhí)行的代碼。通知包好自身的一組規(guī)則。這組規(guī)則規(guī)定了何時(shí)調(diào)用通知,這是與被觸發(fā)的連接點(diǎn)相關(guān)的。

     連接點(diǎn)
            連接點(diǎn)就是可能會(huì)或者可能不會(huì)調(diào)用某個(gè)通知的應(yīng)用程序內(nèi)的特定點(diǎn)。AspectJ中支持的連接點(diǎn):
            被調(diào)用方法時(shí)連接
            在方法執(zhí)行期間連接
            在調(diào)用構(gòu)造函數(shù)時(shí)連接
            在構(gòu)造函數(shù)執(zhí)行期間連接
            在方面通知執(zhí)行期間連接
            在對(duì)象初始化以前連接
            在對(duì)象初始化期間連接
            在靜態(tài)初始化執(zhí)行期間連接
            在引用類(lèi)的字段時(shí)連接
            在給類(lèi)的字段賦值時(shí)連接
            在執(zhí)行處理程序時(shí)連接

     切入點(diǎn)
            切入點(diǎn)是用于聲明連接點(diǎn)中關(guān)注AspectJ機(jī)制,用來(lái)發(fā)起一份通知。

    public class MyClass
    {
      
    public void foo(int number,String name)
      
    {
        System.out.println(
    "Inside foo(int,String)");
      }


      
    public static void main(String[] args)
      
    {
        
    //Create an instance of MyClass
        MyClass myObject = new MyClass();
        
    //Make the call to foo
        myObject.foo(1 , "Russ Miles");
       }

    }

            上述類(lèi)中每一條語(yǔ)句都可看做是潛在的連接點(diǎn)。而下述類(lèi)中則分別申明了切入點(diǎn)和通知。

    public aspect Some Aspect
    {
      
    //A Pointcut declaration
      pointcut somePointcut():<pointcut logic>;

      
    //A block of Advise
      before:somePointcut()
      
    {
        
    //Do something
      }

    }
    posted @ 2008-06-22 23:34 Brian 閱讀(487) | 評(píng)論 (0)編輯 收藏
    一.歸并排序的思路
            ①把 n 個(gè)記錄看成 n 個(gè)長(zhǎng)度為 l 的有序子表;
            ②進(jìn)行兩兩歸并使記錄關(guān)鍵字有序,得到 n/2 個(gè)長(zhǎng)度為 2 的有序子表; 
            ③重復(fù)第②步直到所有記錄歸并成一個(gè)長(zhǎng)度為 n 的有序表為止。
    二.歸并排序算法實(shí)例
            對(duì)于歸并排序算法這類(lèi)的分治算法,其核心就是"分解"和"遞歸求解"。對(duì)于"分解"實(shí)例,會(huì)在下面分析msort()方法中給出。我們先看合并的過(guò)程。
            以下面描述的序列為例,在索引范圍內(nèi)[first , last)的序列還有九個(gè)整數(shù)元素,它由索引范圍為[first , mid]的四個(gè)元素有序子列表A和索引范圍[mid , last]的五個(gè)元素有序子列表B組成。


            步驟1:比較arr[indexA]=7與arr[indexB]=12。將較小的元素7復(fù)制到數(shù)組tempArr的索引indexC處。并將indexA和indexC都指向下一個(gè)位置。


            步驟2:比較arr[indexA]=10與arr[indexB]=12。將較小的元素10復(fù)制到數(shù)組tempArr的索引indexC處。并將indexA和indexC都指向下一個(gè)位置。

            步驟3:比較arr[indexA]=19與arr[indexB]=12。將較小的元素12復(fù)制到數(shù)組tempArr的索引indexC處。并將indexB和indexC都指向下一個(gè)位置。


            步驟4-7:依次成對(duì)比較兩子表的元素將17,19,21,25復(fù)制到數(shù)組tempArr。此時(shí),indexA到達(dá)子表A的未尾(indexA = mid),indexB引用的值為30。

            步驟8-9:將未到尾部的子表剩余數(shù)據(jù)復(fù)制到tempArr中。

            步驟10:將tempArr復(fù)制到原始數(shù)據(jù)arr中。

    三.歸并排序算法的實(shí)現(xiàn)
        了解了合并過(guò)程,那么理解下面的代碼并不是一件難事。下面提供了歸并算法的非泛型版本和泛型版本。
    public class MergeSort {
        
        
    public static void sort(Object[] arr) {
            
    //create a temporary array to store partitioned elements
            Object[] tempArr = arr.clone();

            
    //call msort with arrays arr and tempArr along
            
    //with the index range
            msort(arr, tempArr, 0, arr.length);
        }


        
    public static <extends Comparable<? super T>> void sort(T[] arr) {
            
    //create a temporary aray to store partitioned elements
            T[] tempArr = (T[]) arr.clone();

            
    //call msort with arrays arr and tempArr along
            
    //with the index range
            msort(arr, tempArr, 0, arr.length);
        }


        
    private static void msort(Object[] arr, Object[] tempArr, int first,
                                  
    int last) {
            
    //if the sublist has more than 1 element continue
            if (first + 1 < last) {
                
    //for sublists of size 2 or more, call msort()
                
    //for the left and right sublists and than
                
    //merge the sorted sublists using merge()
                int midpt = (last + first) / 2;

                msort(arr, tempArr, first, midpt);
                msort(arr, tempArr, midpt, last);

                
    //if list is already sorted, just copy src to
                
    //dest; this is an optimization that results in faster
                
    //sorts for nearly ordered lists
                if (((Comparable) arr[midpt - 1]).compareTo(arr[midpt]) <= 0)
                    
    return;
                
    //the elements in the ranges [first,mid] and
                
    //[mid,last] are ordered;merge the ordered sublists
                
    //into an ordered sequence in the range [first , last]
                
    //using the temporary array
                int indexA, indexB, indexC;

                
    //set indexA to scan sublist A with rang [first , mid]
                
    //and indexB to scan sublist B with rang [mid , last]
                indexA = first;
                indexB 
    = midpt;
                indexC 
    = first;

                
    //while both sublists are not exhausted, compare
                
    //arr[indexA] and arr[indexB]; copy the smaller
                
    //to tempArr
                while (indexA < midpt && indexB < last) {
                    
    if (((Comparable) arr[indexA]).compareTo(arr[indexB]) < 0{
                        tempArr[indexC] 
    = arr[indexA]; //copyto tempArr
                        indexA++//increment indexA
                    }
     else {
                        tempArr[indexC] 
    = arr[indexB]; //copyto tempArr
                        indexB++//increment indexB
                    }

                    indexC
    ++//increment indexC
                }

                
    //copy the tail of the sublist that is not exhausted
                while (indexA < midpt) {
                    tempArr[indexC
    ++= arr[indexA++]; //copy to tempArr
                }
     while (indexB < last) {
                    tempArr[indexC
    ++= arr[indexB++]; //copy to tempArr
                }

                
    //copy elements form temporary array to original array
                for (int i = first; i < last; i++)
                    arr[i] 
    = tempArr[i];
            }

        }

    }
            
            上述代碼中最核心的msort()方法是一遞歸算法。下圖說(shuō)明了msort()方法中子列表的分割與合并。    

    四.歸并排序算法的效率
            歸并排序的最壞情況與平均情況運(yùn)行時(shí)間都為O(nlog2n)。假定數(shù)組具有n=2k個(gè)元素。如下圖:
             
            在層數(shù)0上對(duì)msort()方法的第一個(gè)調(diào)用會(huì)產(chǎn)生兩個(gè)遞歸調(diào)用,這兩個(gè)遞歸調(diào)用產(chǎn)生長(zhǎng)度為n/2的兩個(gè)半部分列表,而merge()方法將上述兩個(gè)半部分列表組合的一個(gè)有序的n元素列表;在層數(shù)1上存在兩個(gè)msort()方法的調(diào)用,每個(gè)調(diào)用又會(huì)產(chǎn)生另外兩個(gè)對(duì)長(zhǎng)度為n/4的列表的遞歸調(diào)用。每個(gè)合并會(huì)將兩個(gè)長(zhǎng)度為n/4的子列表連接為一個(gè)長(zhǎng)度為n/2的有序列表;在層數(shù)2上存在對(duì)merge()方法的4=22個(gè)調(diào)用,每個(gè)調(diào)用會(huì)創(chuàng)建一個(gè)長(zhǎng)度為n/4的有序列表。通常,在層數(shù)i上存在對(duì)merge()方法的2i個(gè)調(diào)用,每個(gè)調(diào)用會(huì)創(chuàng)建一個(gè)長(zhǎng)度為n/2i的有序子列表。
            層數(shù)0:存在對(duì)merge()方法的1=20次調(diào)用。這個(gè)調(diào)用對(duì)n個(gè)元素排序。
            層數(shù)1:存在對(duì)merge()方法的2=21次調(diào)用。這個(gè)調(diào)用對(duì)n/2個(gè)元素排序。
            層數(shù)2:存在對(duì)merge()方法的4=22次調(diào)用。這個(gè)調(diào)用對(duì)n/4個(gè)元素排序。
            ......
            層數(shù)i:存在對(duì)merge()方法的2i次調(diào)用。這個(gè)調(diào)用對(duì)n/i個(gè)元素排序。
            在樹(shù)中的每一層,合并涉及具有線性運(yùn)行時(shí)間的n/2i個(gè)元素,這個(gè)線性運(yùn)行時(shí)間需要少于n/2i次的比較。在層數(shù)i上組合的2i個(gè)合并操作需要少于2i*n/2i=n次的比較。假定n=2k,分割過(guò)程會(huì)在n/2k=1的k層數(shù)上終止。那么所有層上完成的工作總量為:k*n = nlog2n。因此msort()方法的最壞情況效率為O(nlog2n)。
    posted @ 2008-06-13 00:54 Brian 閱讀(2318) | 評(píng)論 (3)編輯 收藏
    一.插入排序算法的思路
            
    假定這個(gè)數(shù)組的序是排好的,然后從頭往后,如果有數(shù)比當(dāng)前外層元素的值大,則將這個(gè)數(shù)的位置往后挪,直到當(dāng)前外層元素的值大于或者等于它前面的位置為止。
    二.插入排序算法實(shí)例
            用五個(gè)名字(Monroe,Chin,Flores,Stein和Dare)的列表的插入排序算法為例:
                                           Monroe    從Monroe開(kāi)始

            處理名字Chin        Chine  Monroe    將Chin插入到位置0;Monroe移動(dòng)至位置1

            處理名字Flores     Chine  Flores  Monroe    將Flores插入到位置1;Monroe移動(dòng)至位置2

            處理名字Stein       Chine  Flores  Monroe  Stein    Stein位置正確 

            處理名字Dare       Chine  Dare  Flores  Monroe  Stein    將Dare插入在位置1;列表尾部向右移動(dòng) 

    三.插入排序算法的實(shí)現(xiàn)
    public class InsertSort {
        
    //sort an array of elements using insertion sort

        public static <extends Comparable<? super T>> void sort(T[] arr) {
            
    int i, j, n =
     arr.length;
            T target;

            
    /**
             * place element at index i into the sublist
             * from index 0 to i-1 where 1<= i,
             * so it is in the correct positon
             
    */

            
    for (i = 1; i < n; i++{
                
    //
    index j scans down list from index i looking for
                
    //
    correct position to locate target; assigns it to
                
    //arr at index j

                j = i;
                target 
    =
     arr[i];
                
    //
    locate insertion point by scanning downward as long
                
    //
    as target < arr[j] and we have not encountered the
                
    //beginning of the array

                while (j > 0 && target.compareTo(arr[j - 1]) < 0{
                    
    //shift elements up list to make room for insertion

                    arr[j] = arr[j - 1];
                    j
    --
    ;
                }

                
    //the location is found;insert target
                arr[j] = target;
            }

        }

    }

    四.插入排序算法的效率
            
    假定n是數(shù)組的長(zhǎng)度,那么插入排序需要n-1遍。對(duì)于通用的遍i來(lái)說(shuō),插入操作從arr[0]到arr[i-1]的子列表中,并且需要平均i/2次比較。比較的平均總數(shù)為:
                     T(n) = 1/2 + 2/2 + 3/2 + ...... + (n-2)/2 + (n-1)/2 = n(n-1)/4
            根據(jù)T(n)的主項(xiàng),插入排序算法的平均運(yùn)行時(shí)間為O(n2)。最好情況為O(n),最壞情況為O(n2)。
    posted @ 2008-06-11 23:56 Brian 閱讀(2698) | 評(píng)論 (4)編輯 收藏
    僅列出標(biāo)題
    共5頁(yè): 上一頁(yè) 1 2 3 4 5 

    公告


    導(dǎo)航

    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    統(tǒng)計(jì)

    常用鏈接

    留言簿(4)

    隨筆分類(lèi)

    隨筆檔案

    收藏夾

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 妞干网免费观看视频| 毛片在线免费视频| 成人一a毛片免费视频| 亚洲成av人片天堂网老年人| 亚洲av不卡一区二区三区| 亚洲国产精品成人AV在线 | eeuss影院www天堂免费| 99久9在线|免费| 日本特黄a级高清免费大片| 亚洲国产精品无码一线岛国| 亚洲成a人片在线看| 9久热这里只有精品免费| 国产免费看JIZZ视频| 色噜噜AV亚洲色一区二区| 亚洲日本久久久午夜精品| 中文字幕看片在线a免费| 毛片免费在线视频| 亚洲av永久无码精品表情包| 亚洲人成网站999久久久综合| 野花香在线视频免费观看大全| 好吊妞998视频免费观看在线| 亚洲AV无码乱码国产麻豆穿越 | 亚洲av无码专区在线观看下载| a级毛片视频免费观看| 免费无遮挡无码视频网站| 久久综合图区亚洲综合图区| 久久亚洲色WWW成人欧美| 中文字幕免费在线| 毛茸茸bbw亚洲人| 亚洲国产aⅴ成人精品无吗| 久久A级毛片免费观看| 国产成人精品久久亚洲| 亚洲色偷偷色噜噜狠狠99网| 亚洲午夜成人精品电影在线观看| 亚洲高清不卡视频| a色毛片免费视频| 免费中文字幕不卡视频| 亚洲一区二区三区国产精华液| 一区二区免费视频| 亚洲伊人久久大香线蕉综合图片| 亚洲变态另类一区二区三区|