Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说idea aspectj_idea配置运行环境,希望能够帮助你!!!。
AspectJ安装AspectJ下载AspectJ环境变量配置IDEA下配置AspectJ激活AspectJ支持插件添加aspectjrt.jar依赖或Maven依赖使用AspectJ编译器(ajc)AspectJ简单示例示例一示例二问题记录参考文献
AspectJ 是一个基于 Java 语言的 AOP 框架,提供了强大的 AOP 功能,其他很多 AOP 框架都借鉴或采纳其中的一些思想。
AspectJ 是 Java 语言的一个 AOP 实现,其主要包括两个部分:第一个部分定义了如何表达、定义 AOP 编程中的语法规范,通过这套语言规范,我们可以方便地用 AOP 来解决 Java 语言中存在的交叉关注点问题;另一个部分是工具部分,包括编译器、调试工具等。
AspectJ 是最早、功能比较强大的 AOP 实现之一,对整套 AOP 机制都有较好的实现,很多其他语言的 AOP 实现,也借鉴或采纳了 AspectJ 中很多设计。在 Java 领域,AspectJ 中的很多语法结构基本上已成为 AOP 领域的标准。
安装 AspectJ 首先要到 AspectJ官网下载一个可执行的Jar包。
即可下载到一个可执行的 JAR 包,我下的是 aspectj-1.8.14.jar,使用 java -jar aspectj-1.8.14.jar
命令,
多次单击“Next”按钮, 并选择合适的安装目录,即可成功安装 AspectJ。
在安装了 AspectJ 之后,在其安装目录下,可以看到如下的文件结构:
├─bin // 该路径下存放了 aj、aj5、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 命令:
虽然 AspectJ 是 Eclipse 基金组织的开源项目,而且提供了 Eclipse 的 AJDT 插件(AspectJ Development Tools)来开发 AspectJ 应用,但 AspectJ 并不是只能在 Eclipse 中开发。由于我使用的是 IntelliJ IDEA 2019.1.2 版本,所以这里介绍IDEA中如何开发 AspectJ。
只有专业版(Ultimate)的 IntelliJ IDEA 才支持 AspectJ 的开发,而且 IDEA 也提供了 官方文档。
在专业版 IDEA 中开发 AspectJ,需要确保下述插件被激活:
由于本人使用的是 IDEA 2019.1.3 版本,所以同网上的说法不太一样,配置如下:
这两个插件在 2019 版本已经存在,因此不需要另外搜索进行安装。
添加aspectjrt.jar依赖
在项目中添加 aspectjrt.jar
依赖,aspectjrt.jar
即 AspectJ 安装目录中lib
目录下的 jar 包。
接着进行如下操作,将该 Jar 包添加进项目依赖中:
Project Structure
对话框(Ctrl+Shift+Alt+S)。添加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>
上述两种方法都可以达到同样的效果。
IDEA 默认使用javac
编译器,如果要使用 AspectJ 的编译器ajc
,需要在 IDEA 中进行相应的配置。
打开settings
对话框,然后做如下配置:
实际上,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 框架。
在进行案例测试的过程中,遇到了一系列的问题,总结归纳如下:
1、安装 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 版本统一。但是实际上图中红框标识处根本不需要填写内容。如下图所示:
2、执行过程中遇到这样的错误,错误信息如下:
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。
AspectJ——简介以及在IntelliJ IDEA下的配置
AspectJ入门