AspectJ入门及在IDEA中的配置(二)

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: AspectJ入门及在IDEA中的配置(二)

添加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对话框,然后做如下配置:

image.png

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,我们则不需要修改上面的方法,只需要添加一个切面即可。


image.png


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编译器时错误导致代码执行有误,当时我配置的情况如下图所示:


image.png


图中红框标记处,我以为是填写版本号,但是代码执行之后会报这样的错误:


image.png


错误信息为:


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 编译器配置也发生变化,导致错误发生。


image.png


所以这也是为啥我改为安装 aspectj-1.8.14,当时以为需要和 JDK 版本统一。但是实际上图中红框标识处根本不需要填写内容。如下图所示:


image.png


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。


image.png


相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
目录
相关文章
|
5月前
|
Java 应用服务中间件 Maven
在IntelliJ IDEA中如何配置使用Maven以创建Tomcat环境
所以,别担心这些工具看起来有些吓人,实际上这些都是为了帮助你更好的完成工作的工具,就像超市里的各种烹饪工具一样,尽管它们看起来可能很复杂,但只要你学会用,它们会为你烹饪出一道道美妙的食物。这就是学习新技能的乐趣,让我们一起享受这个过程,攀登知识的高峰!
330 27
|
5月前
|
Java 应用服务中间件 Apache
在IntelliJ IDEA中使用Maven配置Tomcat环境
此配置方法具有较高的实用性,简单易懂。遵循以上步骤,您将能顺利在IntelliJ IDEA中使用Maven配置Tomcat环境,从而进行Web项目的开发和调试。
487 18
|
6月前
|
缓存 Java Spring
IDEA中配置HTML和Thymeleaf热部署的步骤
以上就是在IntelliJ IDEA中配置HTML和Thymeleaf热部署的步骤。这样的配置可以大大提高你的开发效率,让你更专注于代码的编写,而不是等待应用的重启。希望这个指南对你有所帮助!
353 21
|
8月前
|
Java Maven
Idea配置项目的热启动
Idea配置项目的热启动
636 5
Idea配置项目的热启动
|
10月前
|
Java Spring
【Spring配置】idea编码格式导致注解汉字无法保存
问题一:对于同一个项目,我们在使用idea的过程中,使用汉字注解完后,再打开该项目,汉字变成乱码问题二:本来a项目中,汉字注解调试好了,没有乱码了,但是创建出来的新的项目,写的注解又成乱码了。
|
9月前
|
前端开发 Java 开发工具
Git使用教程-将idea本地Java等文件配置到gitte上【保姆级教程】
本内容详细介绍了使用Git进行版本控制的全过程,涵盖从本地仓库创建到远程仓库配置,以及最终推送代码至远程仓库的步骤。
465 0
|
11月前
|
Linux 网络安全 开发工具
IDEA如何配置git和github
【11月更文挑战第14天】本指南详细介绍了如何在 IntelliJ IDEA 中配置 Git 和 GitHub,包括检查和设置 Git 路径、测试配置,以及通过 SSH 或 HTTPS 方式配置 GitHub 仓库的具体步骤。完成配置后,用户可在 IDEA 中轻松进行版本控制操作。
1638 0
|
Android开发
Idea_学习_07_Idea常用配置
      二、参考资料 1、Android Studio 入门级教程(一)
866 0
|
7月前
|
IDE 程序员 开发工具
只用正版!教你5个方法,白嫖JetBrains家族的所有产品,包含:IntelliJ IDEA、PyCharm、WebStorm、CLion、Rider
程序员晚枫分享了5种官方认证的免费使用JetBrains家族产品的方法,包括内容创作者计划、开源项目支持、教育许可证、用户组支持和开发者认可计划。这些方法帮助个人开发者与小型团队合法获取强大开发工具,如IntelliJ IDEA、PyCharm等,降低开发成本,提升效率。同时提醒大家遵守使用规范,尊重知识产权。
1132 13
|
IDE Oracle Java
day4:JDK、IntelliJ IDEA的安装和环境变量配置
【7月更文挑战第4天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
509 0