介绍了动态代理的定义、优势、jvm动态代理实现方式、通过Consumer定制化前置和后置方法。


一、动态代理的定义

动态代理(Dynamic Proxy)是 Java 提供的一种在运行时动态生成代理对象的机制,相较于静态代理为每个目标类都定义一个代理类,动态代理只需要一个实现InvocationHandler的类,通过Proxy.newProxyInstance方法即可自动创建各种目标类的代理类,其原理是反射,速度相较于CGLIB速度较慢。通过 java.lang.reflect.Proxy 类和 InvocationHandler 接口,我们可以实现对原始方法的拦截增强,常用于以下场景:

  • 日志记录
  • 权限校验
  • 事务管理
  • 性能监控

二、动态代理的三大优点

优势 说明
代码解耦 将通用逻辑(如日志)与业务代码分离
高复用性 一个代理处理器可服务于多个接口
运行时动态生成 无需为每个类手动编写代理,由 JVM 动态创建代理类

三、基础使用示例

3.1 定义接口与实现类

1
2
3
4
5
6
7
8
9
interface UserService {
void addUser(String name);
}

class UserServiceImpl implements UserService {
public void addUser(String name) {
System.out.println("添加用户: " + name);
}
}

3.2 通用代理实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class BasicProxy implements InvocationHandler {
private final Object target;

public BasicProxy(Object target) {
this.target = target;
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("【前置通知】");
Object result = method.invoke(target, args);
System.out.println("【后置通知】");
return result;
}

public static Object createProxy(Object target) {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new BasicProxy(target)
);
}
}

四、使用 Consumer 实现灵活拦截

4.1 函数式接口 Consumer

java.util.function.Consumer<T> 是 Java 8 引入的函数式接口,其核心方法是:

1
void accept(T t);

特点:

  • 接收参数不返回值
  • 常用于实现回调逻辑

4.2 增强型代理实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class EnhancedProxy implements InvocationHandler {
private final Object target;
private final Consumer<Method> before;
private final Consumer<Method> after;

public EnhancedProxy(Object target,
Consumer<Method> before,
Consumer<Method> after) {
this.target = target;
this.before = before;
this.after = after;
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before.accept(method); // 执行前置逻辑
Object result = method.invoke(target, args);
after.accept(method); // 执行后置逻辑
return result;
}
}

五、自定义前后置方法实战

5.1 为不同接口定制逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 用户服务代理
UserService userService = (UserService) Proxy.newProxyInstance(
UserServiceImpl.class.getClassLoader(),
new Class[]{UserService.class},
new EnhancedProxy(
new UserServiceImpl(),
method -> System.out.println(">>> 用户操作开始: " + method.getName()),
method -> System.out.println("<<< 用户操作结束: " + method.getName())
)
);

// 娱乐服务代理
EntertainmentService es = (EntertainmentService) Proxy.newProxyInstance(
MovieService.class.getClassLoader(),
new Class[]{EntertainmentService.class},
new EnhancedProxy(
new MovieService(),
method -> System.out.println("★ 娱乐活动准备: " + method.getName()),
method -> System.out.println("☆ 活动结束耗时统计...")
)
);

5.2 执行效果

1
2
3
4
5
6
7
>>> 用户操作开始: addUser
添加用户: Alice
<<< 用户操作结束: addUser

★ 娱乐活动准备: playMovie
播放电影: 星际穿越
☆ 活动结束耗时统计...

六、架构优化总结

方案 优点 适用场景
基础代理 实现简单,快速上手 所有方法需要相同增强逻辑
增强型代理 支持不同接口的差异化处理 需要灵活定制拦截逻辑的场景

最佳实践建议

  1. 使用 Lambda 表达式简化 Consumer 实现
  2. 通过工厂模式封装代理创建过程
  3. 结合注解实现更精细化的方法级控制

代码附录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.function.Consumer;

interface UserService {
void addUser(String username);
void deleteUser(String username);
}

class UserServiceImpl implements UserService {
@Override
public void addUser(String username) {
System.out.println("Adding user: " + username);
}

@Override
public void deleteUser(String username) {
System.out.println("Deleting user: " + username);
}
}

interface Girl {
void watchTV();
}

class Daughter implements Girl {
@Override
public void watchTV() {
System.out.println("watching TV");
}
}

class ServiceProxy implements InvocationHandler {
private final Object target;
private final Consumer<Method> before;
private final Consumer<Method> after;

// 支持自定义前置和后置逻辑的构造函数
public ServiceProxy(Object target, Consumer<Method> before, Consumer<Method> after) {
this.target = target;
this.before = before;
this.after = after;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before.accept(method); // 执行自定义前置逻辑
Object result = method.invoke(target, args);
after.accept(method); // 执行自定义后置逻辑
return result;
}

public Object getProxyInstance() {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this
);
}
}

// 测试类
public class p1 {
public static void main(String[] args) {
// UserService 的代理逻辑
UserService userService = new UserServiceImpl();
ServiceProxy userProxy = new ServiceProxy(
userService,
method -> System.out.println("[用户服务] 准备执行: " + method.getName()),
method -> System.out.println("[用户服务] 完成执行: " + method.getName())
);
UserService proxyUserService = (UserService) userProxy.getProxyInstance();
proxyUserService.addUser("Alice");
proxyUserService.deleteUser("Bob");

// Girl 的代理逻辑
Daughter daughter = new Daughter();
ServiceProxy girlProxy = new ServiceProxy(
daughter,
method -> System.out.println("[女孩行为] 方法开始: " + method.getName()),
method -> System.out.println("[女孩行为] 方法结束: " + method.getName())
);
Girl mother = (Girl) girlProxy.getProxyInstance();
mother.watchTV();
}
}