AspectJ入門及在IDEA中的配置

AspectJ安裝AspectJ下載AspectJ環境變量配置IDEA下配置AspectJ激活AspectJ支持插件添加aspectjrt.jar依賴或Maven依賴使用AspectJ編譯器(ajc)AspectJ簡單示例示例一示例二問題記錄參考文獻php

AspectJ

AspectJ 是一個基於 Java 語言的 AOP 框架,提供了強大的 AOP 功能,其餘不少 AOP 框架都借鑑或採納其中的一些思想。css

AspectJ 是 Java 語言的一個 AOP 實現,其主要包括兩個部分:第一個部分定義瞭如何表達、定義 AOP 編程中的語法規範,經過這套語言規範,咱們能夠方便地用 AOP 來解決 Java 語言中存在的交叉關注點問題;另外一個部分是工具部分,包括編譯器、調試工具等。html

AspectJ 是最先、功能比較強大的 AOP 實現之一,對整套 AOP 機制都有較好的實現,不少其餘語言的 AOP 實現,也借鑑或採納了 AspectJ 中不少設計。在 Java 領域,AspectJ 中的不少語法結構基本上已成爲 AOP 領域的標準。java

安裝AspectJ

下載AspectJ

安裝 AspectJ 首先要到 AspectJ官網下載一個可執行的Jar包。web

便可下載到一個可執行的 JAR 包,我下的是 aspectj-1.8.14.jar,使用 java -jar aspectj-1.8.14.jar 命令, spring

屢次單擊「Next」按鈕, 並選擇合適的安裝目錄,便可成功安裝 AspectJ。 apache

在安裝了 AspectJ 以後,在其安裝目錄下,能夠看到以下的文件結構: 編程

├─bin // 該路徑下存放了 aj、aj五、ajc、ajdoc、ajbrowser 等命令。
│  ├─aj.bat
│  ├─aj5.bat
│  ├─ajbrowser
│  ├─ajbrowser.bat
│  ├─ajc // 其中 ajc 命令最經常使用,它的做用相似於 javac,用於對普通 Java 類進行編譯時加強。
│  ├─ajc.bat
│  ├─ajdoc
│  ├─ajdoc.bat
├─doc // 該路徑下存放了AspectJ的使用說明、參考手冊、API文檔等文檔。
├─lib // 該路徑下的4個Jar文件是AspectJ的核心類庫
│  ├─aspectjrt.jar
│  ├─aspectjtools.jar
│  ├─aspectjweaver.jar
│  ├─org.aspectj.matcher.jar
├─LICENSE-AspectJ.html    相關受權文件
└─README-AspectJ.html
複製代碼

環境變量配置

CLASSPATH:.;D:\Java_About\Java_component\aspectj-1.8.14\lib\aspectjrt.jar;

Path:D:\Java_About\Java_component\aspectj-1.8.14\bin
複製代碼

測試是否安裝成功用 ajc 命令:微信

IDEA下配置AspectJ

雖然 AspectJ 是 Eclipse 基金組織的開源項目,並且提供了 Eclipse 的 AJDT 插件(AspectJ Development Tools)來開發 AspectJ 應用,但 AspectJ 並非只能在 Eclipse 中開發。因爲我使用的是 IntelliJ IDEA 2019.1.2 版本,因此這裏介紹IDEA中如何開發 AspectJ。app

只有專業版(Ultimate)的 IntelliJ IDEA 才支持 AspectJ 的開發,並且 IDEA 也提供了 官方文檔

激活AspectJ支持插件

在專業版 IDEA 中開發 AspectJ,須要確保下述插件被激活:

  • Spring AOP/@AspectJ
  • AspectJ Support

因爲本人使用的是 IDEA 2019.1.3 版本,因此同網上的說法不太同樣,配置以下:

這兩個插件在 2019 版本已經存在,所以不須要另外搜索進行安裝。

添加aspectjrt.jar依賴或Maven依賴

添加aspectjrt.jar依賴

在項目中添加 aspectjrt.jar依賴,aspectjrt.jar即 AspectJ 安裝目錄中lib目錄下的 jar 包。

接着進行以下操做,將該 Jar 包添加進項目依賴中:

  1. 打開 Project Structure 對話框(Ctrl+Shift+Alt+S)。
  2. 對應於建立項目級別的或者IDE級別的庫,分別選擇 Libraries 或者 Global Libraries。
  3. 點擊+號並選擇 java。
  4. 在彈出的對話框中,選擇剛纔咱們添加進項目的lib目錄下的 aspectjrt.jar 文件。
  5. 最後點擊OK按鈕便可。

添加Maven依賴

若是採用 Maven 來管理項目,則能夠在 pom.xml 文件中添加相關依賴。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.msdn</groupId>
    <artifactId>spring_aop</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.14</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>1.8.14</version>
        </dependency>
    </dependencies>
</project>
複製代碼

上述兩種方法均可以達到一樣的效果。

使用AspectJ編譯器(ajc)

IDEA 默認使用javac編譯器,若是要使用 AspectJ 的編譯器ajc,須要在 IDEA 中進行相應的配置。

打開settings對話框,而後作以下配置:

AspectJ簡單示例

實際上,AspectJ 的用法很是簡單,就像咱們使用 JDK 編譯、運行 Java 程序同樣。下面經過一個簡單的程序來示範 AspectJ 的用法,並分析 AspectJ 如何在編譯時進行加強。

示例一

HelloWorld.java

public class HelloWorld {
    public void sayHello(){
        System.out.println("Hello AspectJ");
    }

    public static void main(String[] args) {
        HelloWorld hello = new HelloWorld();
        hello.sayHello();
    }
}
複製代碼

該類中有一個 sayHello()方法,該方法打印出了一句話!

假設如今咱們須要在 sayHello()方法以前啓動事務,當該方法結束時關閉事務,那麼在傳統的編程模式下,咱們必須手動修改 sayHello()方法。而若是使用 AspectJ,咱們則不須要修改上面的方法,只須要添加一個切面便可。

TxAspect.aj

public aspect TxAspect {
    void around():call(void HelloWorld.sayHello()){
        System.out.println("開始事務。。。");
        proceed();
        System.out.println("結束事務。。。");
    }
}
複製代碼

上面的 TxAspect 根本不是一個 Java 類,因此 aspect 也不是 Java 支持的關鍵字,它只是 AspectJ 才能識別的關鍵字。 其後綴爲.aj,該文件的完整文件名爲TxAspect.aj。切面的語法只有AspectJ能夠識別,並使用其特殊的編譯器ajc來編譯。

這段代碼攔截Hello.sayHello()方法,並在其執行以前開始事務,proceed()方法表明回調原來的sayHello()方法,執行結束後結束事務。

執行結果爲:

開始事務。。。
Hello AspectJ
結束事務。。。
複製代碼

從上面運行結果來看,咱們徹底能夠不對 HelloWorld.java 類進行任何修改,就給它插入了事務管理的功能,這正是面向切面編程的意義所在。從這個例子中咱們也能夠體會到 AspectJ 的易學易用、無侵入(不須要繼承任何類和接口)的特性。

示例二

除了上述事務管理的功能,還能夠在 sayHello()方法後增長記錄日誌的功能。咱們再定義一個 LogAspect,

LogAspect.aj

public aspect LogAspect {

    // 定義一個 PointCut,其名爲 logPointcut
    // 該 PointCut 對應於指定 HelloWorld 對象的 sayHello 方法
    pointcut logPointCut():execution(void HelloWorld.sayHello());

    // 在 logPointcut 以後執行下面代碼塊
    after():logPointCut(){
        System.out.println("記錄日誌。。。。");
    }
}
複製代碼

上述代碼定義了一個 Pointcut:logPointcut - 等同於執行 HelloWorld 對象的 sayHello() 方法,並指定在 logPointcut 以後執行簡單的代碼塊,也就是說,在 sayHello() 方法以後執行指定代碼塊。

執行結果爲:

開始事務。。。
Hello AspectJ
記錄日誌。。。。
結束事務。。。
複製代碼

從上面運行結果來看,經過使用 AspectJ 提供的 AOP 支持,咱們能夠爲 sayHello() 方法不斷增長新功能。

爲何在對 HelloWorld 類沒有任何修改的前提下,而 HelloWorld 類能不斷地、動態增長新功能呢?這看上去並不符合 Java 基本語法規則啊。實際上咱們可使用 Java 的反編譯工具來反編譯前面程序生成的 HelloWorld.class 文件,發現 HelloWorld.class 文件的代碼以下:

public class HelloWorld {
    public HelloWorld() {
    }

    public void sayHello() {
        try {
            System.out.println("Hello AspectJ");
        } catch (Throwable var2) {
            LogAspect.aspectOf().ajc$after$com_msdn_aspectj_LogAspect$1$9e12ed77();
            throw var2;
        }

        LogAspect.aspectOf().ajc$after$com_msdn_aspectj_LogAspect$1$9e12ed77();
    }

    public static void main(String[] args) {
        HelloWorld hello = new HelloWorld();
        sayHello_aroundBody1$advice(hello, TxAspect.aspectOf(), (AroundClosure)null);
    }
}
複製代碼

不難發現這個 HelloWorld.class 文件不是由原來的 HelloWorld.java 文件編譯獲得的,該 HelloWorld.class 裏新增了不少內容,sayHello() 方法中增長了日誌功能,主方法中增長了事務管理功能——這代表 AspectJ 在編譯時「自動」編譯獲得了一個新類,這個新類加強了原有的 HelloWorld.java 類的功能,所以 AspectJ 一般被稱爲編譯時加強的 AOP 框架。

問題記錄

在進行案例測試的過程當中,遇到了一系列的問題,總結概括以下:

一、安裝 AspectJ 時,我首先安裝的是 aspectj-1.9.2 版本,可是後續實際測試過程當中,因爲在 IDEA 中配置AspectJ編譯器時錯誤致使代碼執行有誤,當時我配置的狀況以下圖所示:

圖中紅框標記處,我覺得是填寫版本號,可是代碼執行以後會報這樣的錯誤:

錯誤信息爲:

Error:ajc: Compliance level '1.8' is incompatible with target level '9'. A compliance level '9' or better is required
複製代碼

緣由:本地使用的 JDK 版本爲 1.8,此處若是配置1.9的話,會致使 Javac 編譯器配置也發生變化,致使錯誤發生。

因此這也是爲啥我改成安裝 aspectj-1.8.14,當時覺得須要和 JDK 版本統一。可是實際上圖中紅框標識處根本不須要填寫內容。以下圖所示:

二、執行過程當中遇到這樣的錯誤,錯誤信息以下:

Error: java: Compliance level '1.6' is incompatible with target level '1.8'. A compliance level '1.8' or better is required
複製代碼

點擊 File 標籤裏的 Project Structure,選擇 Project Settings->Modules,選擇1.8版本對應的 language level。

微信截圖_20200214130526
微信截圖_20200214130526

參考文獻

AspectJ——簡介以及在IntelliJ IDEA下的配置

AspectJ入門

相關文章
相關標籤/搜索