aspectj編程簡介

  如今java生態中spring大行其道,通常使用aspectj進行切面編程使用註解方式實現,比較少使用原生的aspectj編程,網上的資料也比較少。最近工做中須要封裝redisson客戶端提供統一的redis組件,主要就是實現耗時日誌打印以及上報,壓測支持等功能。爲了不組件依賴spring的狀況,使用了aspectj原生庫編程。工程基於jdk1.8。java

1.aspectj介紹

  aspectj定義(來自wiki):AspectJ是在PARC爲Java編程語言建立的面向方面的編程擴展。它能夠在Eclipse Foundation開源項目中使用,既能夠單獨使用,也能夠集成到Eclipse中。redis

  關於面向切面編程,這裏再也不贅述,通常用於實現通用的功能,好比日誌打印,權限控制等。aspectj經過定義切面,將spring

2.配置以及使用

2.1配置

  aspectj依賴兩個核心庫(aspectjrt,aspectjweaver),因此在須要在工程pom文件中添加一下依賴編程

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.9</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>

  要使aspectj織入功能生效還須要添加aspectj-maven-plugin插件,配置以下。數據結構

<build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.7</version>
                <configuration>
                    <complianceLevel>1.8</complianceLevel>
                    <source>1.8</source>
                    <target>1.8</target>
                    <showWeaveInfo>true</showWeaveInfo>
                    <verbose>true</verbose>
                    <Xlint>ignore</Xlint>
                    <encoding>UTF-8</encoding>
                    <weaveDependencies>
                        <weaveDependency>
                            <groupId>org.redisson</groupId>
                            <artifactId>redisson</artifactId>
                        </weaveDependency>
                    </weaveDependencies>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <!-- use this goal to weave all your main classes -->
                            <goal>compile</goal>
                            <!-- use this goal to weave all your test classes -->
                            <!--<goal>test-compile</goal>-->
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

  aspectj能夠選擇織入的時期,主要分爲三種:編譯時,編譯後,運行期。編譯時織入只對織入代碼在本工程的狀況,編譯後織入除了本工程代碼還包括針對織入代碼在第三方jar包狀況,運行時織入只有在代碼運行時才作動態切面。上面這個例子是編譯後的配置,其中weaveDependencies配置了第三方jar包信息,只須要編譯是織入能夠不用配置。運行時織入參考(https://www.baeldung.com/aspectj)maven

2.2 aspect編寫

  切面類代碼以下編程語言

/** * @date 2018/12/22
 */
public aspect CommandAspect {

    /**
     * redis命令方法切面,全部redis命令都會通過
     */
    public pointcut callSendCommand():
            execution (* org.redisson.command.CommandAsyncService.sendCommand(..));

    /**
     * RedissonExpirable的全部子類方法切面,基本包含了redisson內置的經常使用數據結構
     */
    public pointcut callExpireSubClassMethod():
            execution (* org.redisson.RedissonExpirable+.*(..));


    Object around(): callSendCommand() {
        //long startNs = System.nanoTime();
        Object result = proceed();
        //AspectUtil.sendMetrics(startNs, thisJoinPoint);
        return result;
    }

    Object around(): callExpireSubClassMethod(){
        Object result = proceed();
        //AspectUtil.resetExpireTime(thisJoinPoint);
        return result;
    }
}

  對於熟悉註解方式實現的同窗能夠發現,這種方式與註解方式十分相像,這裏是實現了around,一樣也支持before,after方式。在idea intellij調試時,沒法在apsect類中斷點,可是能夠在其依賴的class類中斷點,這對於咱們第一次編碼的時候存在一些困擾。ide

  編碼完成後,使用mvn compile命令,實現代碼織入,以後就能夠進行調試了ui

 

參考文檔:this

http://opoo.org/aspectj-compile-time-weaving/

https://www.baeldung.com/aspectj

相關文章
相關標籤/搜索