使用AspectJ实现AOP
程序员文章站
2022-05-24 12:27:43
...
AOP专门用于处理系统中分布于各个模块(不同方法)中的交叉关注点的问题,在JavaEE应用中,常常通过AOP来处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等,AOP已经成为一种非常常用的解决方案。
在学习SpringAOP之前,我们先来简单看看AspectJ。
AspectJ是一个基于Java语言的AOP框架,提供了强大的AOP功能,其他很多AOP框架都借鉴或采纳其中的一些思想。由于Spring3.0的AOP与AspectJ进行了很好的集成,因此掌握AspectJ是学习SpringAOP的基础。
AspectJ主要包括两个部分:
部分 | 描述 |
第一部分 | 定义了如何表达、定义AOP编程中的语法规范,通过这套规范,我们可以方便地用AOP来解决Java语言中存在的交叉关注点问题。 |
另一部分 | 工具部分,包括编译器、调试工具等。 |
package com.ant;
public class Hello{
public static void main(String[] args){
Hello hello = new Hello();
hello.sayHello();
}
public void sayHello(){
System.out.println("Hello AspectJ!");
}
}
package com.ant;
public aspect TxAspect{
void around():call(void Hello.sayHello()){
System.out.println("Transaction start...");
proceed();
System.out.println("Transaction end...");
}
}
package com.ant;
public aspect LogAspect{
pointcut logPointcut():execution(void Hello.sayHello());
after():logPointcut(){
System.out.println("log...");
}
}
我们利用javap反编译生成的Hello.class,可以发现它不是由Hello.java编译得到的,该Hello.class文件内新增了很多内容------这表明AspectJ在编译时已经增强了Hello.class的功能,因此AspectJ通常被称为编译时增强的AOP框架。
Compiled from "Hello.java"
public class com.ant.Hello {
public com.ant.Hello();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #1 // class com/ant/Hello
3: dup
4: invokespecial #17 // Method "<init>":()V
7: astore_1
8: aload_1
9: astore_2
10: aload_2
11: invokestatic #56 // Method com/ant/TxAspect.aspectOf:()Lcom/ant/TxAspect;
14: aconst_null
15: invokestatic #60 // Method sayHello_aroundBody1$advice:(Lcom/ant/Hello;Lcom/ant/TxAspect;Lorg/aspectj/runtime/internal/AroundClosure;)V
18: return
public void sayHello();
Code:
0: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #30 // String Hello AspectJ!
5: invokevirtual #32 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: goto 20
11: astore_1
12: invokestatic #67 // Method com/ant/LogAspect.aspectOf:()Lcom/ant/LogAspect;
15: invokevirtual #70 // Method com/ant/LogAspect.ajc$after$com_ant_LogAspect$1$9fd5dd97:()V
18: aload_1
19: athrow
20: invokestatic #67 // Method com/ant/LogAspect.aspectOf:()Lcom/ant/LogAspect;
23: invokevirtual #70 // Method com/ant/LogAspect.ajc$after$com_ant_LogAspect$1$9fd5dd97:()V
26: return
Exception table:
from to target type
0 11 11 Class java/lang/Throwable
private static final void sayHello_aroundBody0(com.ant.Hello);
Code:
0: aload_0
1: invokevirtual #18 // Method sayHello:()V
4: return
private static final void sayHello_aroundBody1$advice(com.ant.Hello, com.ant.TxAspect, org.aspectj.runtime.internal.AroundClosure);
Code:
0: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #44 // String Transaction start...
5: invokevirtual #32 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: aload_2
9: astore_3
10: aload_0
11: invokestatic #62 // Method sayHello_aroundBody0:(Lcom/ant/Hello;)V
14: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream;
17: ldc #52 // String Transaction end...
19: invokevirtual #32 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
22: return
}
与AspectJ相对的还有另外一种AOP框架,它们不需要在编译时对目标类进行增强,而是运行时生成目标类的代理类,该代理类要么与目标类实现相同的接口,要么是目标类的子类------总之,代理类都对目标类进行了增强处理,前者是JDK动态代理的处理策略,后者是cglib代理的处理策略。SpringAOP以创建动态代理的方式来生成代理类,底层既可使用JDK动态代理,也可采用cglib代理。
转载于:https://my.oschina.net/u/2914561/blog/777808
推荐阅读
-
Vue 中使用vue2-highcharts实现曲线数据展示的方法
-
Laravel框架使用Seeder实现自动填充数据功能
-
Python使用win32com模块实现数据库表结构自动生成word表格的方法
-
对python使用telnet实现弱密码登录的方法详解
-
python使用PIL实现多张图片垂直合并
-
使用python实现拉钩网上的FizzBuzzWhizz问题示例
-
vue 不使用select实现下拉框功能(推荐)
-
JavaScript编程开发中如何使用jquery实现放大镜效果
-
Android 中使用 dlib+opencv 实现动态人脸检测
-
python使用cStringIO实现临时内存文件访问的方法