1
1
import java .lang .reflect .InvocationHandler ;
2
2
import java .lang .reflect .Method ;
3
3
import java .lang .reflect .Proxy ;
4
-
4
+ import java .util .ArrayList ;
5
+ import java .util .List ;
5
6
/*
6
7
AOP(面向切面编程)是一种编程范式,通过分离横切关注点来提高模块性。
7
8
横切关注点是跨越应用程序多个部分的功能,比如日志记录、事务管理等。
8
9
在 Java 中,主要是通过 Java 的反射机制和动态代理来实现 AOP 。
9
10
态代理允许在运行时创建一个实现了特定接口的代理对象,我们可以在代理对象的方法调用前后插入额外的逻辑,从而实现 AOP 的功能。
10
11
*/
11
12
12
- // 1. 定义业务接口
13
- interface UserService {
14
- void addUser ( String username );
13
+ // 1. 定义通用的切面接口(可扩展)
14
+ interface Aspect {
15
+ void before ( Method method , Object [] args );
15
16
16
- void deleteUser ( int userId );
17
+ void after ( Method method , Object result );
17
18
}
18
19
19
- // 2. 实现业务接口
20
- class UserServiceImpl implements UserService {
20
+ // 2. 日志切面实现
21
+ class LoggingAspect implements Aspect {
21
22
@ Override
22
- public void addUser ( String username ) {
23
- System .out .println ("添加用户: " + username );
23
+ public void before ( Method method , Object [] args ) {
24
+ System .out .println ("前置通知: 调用 " + method . getName () + ",参数: " + java . util . Arrays . toString ( args ) );
24
25
}
25
26
26
27
@ Override
27
- public void deleteUser ( int userId ) {
28
- System .out .println ("删除用户 : " + userId );
28
+ public void after ( Method method , Object result ) {
29
+ System .out .println ("后置通知 : " + method . getName () + " 执行完成,返回值: " + result );
29
30
}
30
31
}
31
32
32
- // 3. 定义切面类
33
- class LoggingAspect {
34
- public void before () {
35
- System .out .println ("前置通知: 准备执行操作" );
33
+ // 3. 通用动态代理类
34
+ class DynamicProxy implements InvocationHandler {
35
+ private final Object target ; // 目标对象
36
+ private final List <Aspect > aspects ; // 切面列表
37
+
38
+ public DynamicProxy (Object target , List <Aspect > aspects ) {
39
+ this .target = target ;
40
+ this .aspects = aspects ;
41
+ }
42
+
43
+ @ Override
44
+ public Object invoke (Object proxy , Method method , Object [] args ) throws Throwable {
45
+ for (Aspect aspect : aspects ) {
46
+ aspect .before (method , args );
47
+ }
48
+ Object result = method .invoke (target , args ); // 调用目标方法
49
+ for (Aspect aspect : aspects ) {
50
+ aspect .after (method , result );
51
+ }
52
+ return result ;
36
53
}
37
54
38
- public void after () {
39
- System .out .println ("后置通知: 操作执行完成" );
55
+ // 创建代理对象的通用方法
56
+ @ SuppressWarnings ("unchecked" )
57
+ public static <T > T createProxy (T target , List <Aspect > aspects ) {
58
+ return (T ) Proxy .newProxyInstance (
59
+ target .getClass ().getClassLoader (),
60
+ target .getClass ().getInterfaces (),
61
+ new DynamicProxy (target , aspects ));
40
62
}
41
63
}
42
64
43
- // 4. 创建动态代理类
44
- class UserServiceProxy implements InvocationHandler {
45
- private Object target ; // 目标对象(被代理的对象)
46
- private LoggingAspect aspect ; // 切面对象(包含横切逻辑)
65
+ // 4. 业务接口
66
+ interface UserService {
67
+ void addUser (String username );
47
68
48
- // 构造函数,传入目标对象和切面对象
49
- public UserServiceProxy (Object target , LoggingAspect aspect ) {
50
- this .target = target ;
51
- this .aspect = aspect ;
69
+ void deleteUser (int userId );
70
+ }
71
+
72
+ // 5. 业务实现类
73
+ class UserServiceImpl implements UserService {
74
+ @ Override
75
+ public void addUser (String username ) {
76
+ System .out .println ("添加用户: " + username );
52
77
}
53
78
54
- // 实现 InvocationHandler 接口的 invoke 方法
55
79
@ Override
56
- public Object invoke (Object proxy , Method method , Object [] args ) throws Throwable {
57
- aspect .before (); // 前置通知:在目标方法执行前调用
58
- Object result = method .invoke (target , args ); // 调用目标方法
59
- aspect .after (); // 后置通知:在目标方法执行后调用
60
- return result ; // 返回目标方法的执行结果
80
+ public void deleteUser (int userId ) {
81
+ System .out .println ("删除用户: " + userId );
61
82
}
62
83
}
63
84
64
- // 5. 测试AOP
85
+ // 6. 测试 AOP 代理
65
86
public class AOP {
66
87
public static void main (String [] args ) {
67
88
// 创建目标对象
68
89
UserService userService = new UserServiceImpl ();
69
90
70
- // 创建切面对象
71
- LoggingAspect aspect = new LoggingAspect ();
91
+ // 创建切面列表
92
+ List <Aspect > aspects = new ArrayList <>();
93
+ aspects .add (new LoggingAspect ()); // 可以添加多个切面
72
94
73
- // 通过动态代理创建代理对象
74
- UserService proxy = (UserService ) Proxy .newProxyInstance (
75
- userService .getClass ().getClassLoader (), // 目标类的类加载器
76
- userService .getClass ().getInterfaces (), // 目标类实现的接口
77
- new UserServiceProxy (userService , aspect ) // InvocationHandler 实现类
78
- );
95
+ // 通过动态代理创建 UserService 代理对象
96
+ UserService proxy = DynamicProxy .createProxy (userService , aspects );
79
97
80
- // 通过代理对象调用 UserService 的方法
81
- // 调用 addUser 方法时,会先执行前置通知,再执行目标方法,最后执行后置通知
98
+ // 调用代理方法,自动执行 AOP 逻辑
82
99
proxy .addUser ("张三" );
83
-
84
- // 调用 deleteUser 方法时,同样会先执行前置通知,再执行目标方法,最后执行后置通知
85
100
proxy .deleteUser (101 );
86
101
}
87
102
}
88
-
89
103
/*
90
- * jarry@Mac java % javac AOP.java
91
- * jarry@Mac java % java AOP
92
- * 前置通知: 准备执行操作
93
- * 添加用户: 张三
94
- * 后置通知: 操作执行完成
95
- * 前置通知: 准备执行操作
96
- * 删除用户: 101
97
- * 后置通知: 操作执行完成
104
+ jarry@MacBook-Pro java % java AOP.java
105
+ 前置通知: 调用 addUser,参数: [张三]
106
+ 添加用户: 张三
107
+ 后置通知: addUser 执行完成,返回值: null
108
+ 前置通知: 调用 deleteUser,参数: [101]
109
+ 删除用户: 101
110
+ 后置通知: deleteUser 执行完成,返回值: null
98
111
*/
0 commit comments