Aspect Ajc 编译期增强
今天介绍如何使用
Aspect
Ajc
编译器,在编译期间对代码进行增强.
切面类
@Aspect
public class MyAspect {
private static final Logger LOG = LoggerFactory.getLogger(MyAspect.class);
@Before("execution(* org.devx.spring.certified.professional.edu.course.a09.aopajc.MyService.*())")
public void before() {
LOG.info("*********************** MyAspect before ***********************");
}
}
目标类
public class MyService {
private static final Logger LOG = LoggerFactory.getLogger(MyService.class);
public void hello() {
LOG.info("{} hello" , this.getClass());
fun0();
}
public void fun0() {
LOG.info("************************ fun0 ************************");
}
public static void fun1() {
LOG.info("************************ fun1 ************************");
}
}
public class A09Application {
private static final Logger LOG = LoggerFactory.getLogger(A09Application.class);
public static void main(String[] args) {
new MyService().hello();
// 可以增强 static 方法
MyService.fun1();
}
}
运行测试代码得到如下日志输出,从测试结果上来看对 static
方法也实现了增强,对方法内部调用的同类中的方法也实现了增强,功能很强大。
21:56:15.756 [main] INFO org.devx.spring.certified.professional.edu.course.a09.aopajc.MyAspect - *********************** MyAspect before ***********************
21:56:15.759 [main] INFO org.devx.spring.certified.professional.edu.course.a09.aopajc.MyService - class org.devx.spring.certified.professional.edu.course.a09.aopajc.MyService hello
21:56:15.761 [main] INFO org.devx.spring.certified.professional.edu.course.a09.aopajc.MyAspect - *********************** MyAspect before ***********************
21:56:15.761 [main] INFO org.devx.spring.certified.professional.edu.course.a09.aopajc.MyService - ************************ fun0 ************************
21:56:15.761 [main] INFO org.devx.spring.certified.professional.edu.course.a09.aopajc.MyAspect - *********************** MyAspect before ***********************
21:56:15.761 [main] INFO org.devx.spring.certified.professional.edu.course.a09.aopajc.MyService - ************************ fun1 ************************
Ajc 编译后的目标类
编译时直接对
class
文件进行修改,所以无论是静态方法还是非静态方法都可以进行增强。
public class MyService {
private static final Logger LOG = LoggerFactory.getLogger(MyService.class);
public MyService() {
}
public void hello() {
MyAspect.aspectOf().before();
LOG.info("{} hello", this.getClass());
this.fun0();
}
public void fun0() {
MyAspect.aspectOf().before();
LOG.info("************************ fun0 ************************");
}
public static void fun1() {
MyAspect.aspectOf().before();
LOG.info("************************ fun1 ************************");
}
}
如何使用 Ajc 编译
Ajc
编译与Lombok
存在冲突,一起使用时会存在问题。
在 pom.xml
中加入 aspectj-maven-plugin
插件。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.14.0</version>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>8</source>
<target>8</target>
<showWeaveInfo>true</showWeaveInfo>
<verbose>true</verbose>
<xlint>ignore</xlint>
<encoding>UTF-8</encoding>
<weaveDirectories>
<weaveDirectory>${project.build.directory}/classes</weaveDirectory>
</weaveDirectories>
</configuration>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
在 idea
Java Compiler
配置中选择使用 Ajc
编译。
更多的技术干货、原理会在系列文章的后续内容中提供。该文章会同步在微信公众号 【DevXJava】, 方便在微信客户端阅读。
DevXJava 不止于技术