Java AOP (1) compile time weaving 【Java 切面编程 (1) 编译期织入】

时间:2023-12-13 21:59:02

According to wikipedia

 aspect-oriented programming (AOP) is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns

Let's imagine we have serveral modules in a project, each of the them is working well until one day the team decide to dig up more information. The desire to add more logs in the project increases while the effort to change the existing codes is huge, it stops the team from moving on bravely.

Somehow the spread of aop cheers the team. According the story, we just need to add a few classes to change the whole project. For example, one class can add entry log to every mothod. It slightly impact the performance and changes almost nothing of the existing codes. A small modification, an encouraging benefit.

AOP(面向切面编程) 通过隔离切面逻辑来提高模块性

假设我们的项目现在已经有不少模块,它们都很正常的运行着。突然有一天,团队想要从现有项目挖掘出更多的信息。比如,通过全面的方法调用日志来作服务监控。一个一个方法的去添加日志固然可以,然而写起来很枯燥也很花时间,这让队伍有所顾虑。

这时,一条好消息传来。据说有个叫AOP的东西可以通过增加很少量的代码就对整个项目进行修改。举个例子,添加一个的切面类就可以给所有方法加上调用日志。可以说在无需触碰现有代码,也不太影响项目性能的情况下,获得了不小的收益。

There are several ways to enhance the current codes using aop:

1) compile time enhancement

2) post compile enhancement

3) load time enhancement

4) run time enhancement

切面编程有许多方法

1) 编译期代码增强

2) 已有二进制代码增强(比如增强第三方库)

3) jvm类加载期代码增加

4) 运行时代码增强

This chapter will show an example of compile time weaving.

这一节会简单介绍下编译器代码织如的方法

Write a simple service

写一个简单的订阅服务

public class BookingService {
    public void book() {
        System.out.println("Booked a room");
    }
}

A test class

一个切面测试类

public class AspectTest {
    public static void main(String[] args) throws Exception {
        BookingService bookingService = new BookingService();
        bookingService.book();
    }
}

An aspect class (it's a special class and may not be recoginzed correctly by IDE)

切面类 (IDE可能无法很好识别这个文件)

package aop.compile;

import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;

public aspect TrialAspect{        before():execution(* aop.compile.BookingService.*(..)){        System.out.println("----------log before method excecution----------");        }}

Now, execute weaving command in terminal and run enhanced main class

现在,用ajc编译代码并运行测试类

ajc -d . *.java

java aop.compile.AspectTest

The terminal displays the result as expected. Every time the booking service is called, an entry log will be recorded.

标记部分便是切面逻辑。每次订阅服务有被调用,就会增加一条调用日志

----------log before method excecution----------
Booked a room

Before weaving, the directory looks this way

代码织入之前,目录结构是这样的

Java AOP (1) compile time weaving 【Java 切面编程 (1) 编译期织入】

After weaving, we found the enhanced class files

运行完ajc之后,可以看到编译出的class文件

Java AOP (1) compile time weaving 【Java 切面编程 (1) 编译期织入】

Take a look at the BookingService.class, the marked line on which the enhancement relies is used for log purpose.

点开订阅服务的代码一看,原来切面逻辑(打日志)已经写入了book方法

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package aop.compile;

import aop.compile.TrialAspect;

public class BookingService {
    public BookingService() {
    }

    public void book() {
        $a8643223();
        System.out.println("Booked a room");
    }
}

Till this step, the demo is finished.

至此,演示结束

How to use AspectJ

如何使用AspectJ

1. Download aspectj jar from https://eclipse.org/aspectj/

先从官网下载aspectj jar包

2. Install aspectj

安装

java -jar aspectj-xx.jar

an installation window pops up

安装时会弹出窗口

Java AOP (1) compile time weaving 【Java 切面编程 (1) 编译期织入】

by default, aspectj will be installed in C: driver

3. Configure path and classpath environment variables.

配置环境变量和类路径

Add C:\aspectj1.8\lib\aspectjrt.jar;C:\aspectj1.8\lib\aspectjtools.jar --> classpath

Add C:\aspectj1.8\bin --> path

4. Check installation

检查安装

Java AOP (1) compile time weaving 【Java 切面编程 (1) 编译期织入】