Java动态代理基础
# 代理模式
为其他对象提供一个代理以控制对某个对象的访问。代理类主要负责为委托了(真实对象)预处理消息、过滤消息、传递消息给委托类,代理类不现实具体服务,而是利用委托类来完成服务,并将执行结果封装处理。
其实就是代理类为被代理类预处理消息、过滤消息并在此之后将消息转发给被代理类,之后还能进行消息的后置处理。代理类和被代理类通常会存在关联关系(即上面提到的持有的被带离对象的引用),代理类本身不实现服务,而是通过调用被代理类中的方法来提供服务。
代理模式是设计模式中非常重要的一种类型,而设计模式又是编程中非常重要的知识点,特别是在业务系统的重构中,更是有举足轻重的地位。代理模式从类型上来说,可以分为 静态代理和动态代理两种类型。
# 使用
首先看一下静态代理的实现:
//做蛋糕的机器
public interface CakeMachine{
void makeCake();
}
//专门做水果蛋糕的机器
class FruitCakeMachine implements CakeMachine{
public void makeCake() {
System.out.println("Making a fruit cake...");
}
}
// 静态代理 杏仁蛋糕代理
public class ApricotCakeProxy implements CakeMachine{
private CakeMachine cakeMachine;
public ApricotCakeProxy(CakeMachine cakeMachine) {
this.cakeMachine = cakeMachine;
}
public void makeCake() {
cakeMachine.makeCake();
System.out.println("adding apricot...");
}
}
//蛋糕店
public class CakeShop {
public static void main(String[] args) {
//可以给各种各样的蛋糕加上杏仁
FruitCakeMachine fruitCakeMachine = new FruitCakeMachine();
ApricotCakeProxy apricotProxy = new ApricotCakeProxy(fruitCakeMachine);
apricotProxy.makeCake();
apricotProxy = new ApricotCakeProxy(new ChocolateCakeMachine());
apricotProxy.makeCake();
}
}
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
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
下面看一下如何用Java动态代理实现:
// Java动态代理
public class ApricotHandler implements InvocationHandler {
private Object object;
public ApricotHandler(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(object, args);
System.out.println("添加杏仁");
return result;
}
}
public class CakeShop {
public static void main(String[] args) {
//动态代理(可以同时给蛋糕、面包等加杏仁)
//给蛋糕加上杏仁
FruitCakeMachine fruitCakeMachine = new FruitCakeMachine();
ApricotHandler apricotHandler = new ApricotHandler(fruitCakeMachine);
CakeMachine cakeMachine = (CakeMachine) Proxy.newProxyInstance(fruitCakeMachine.getClass().getClassLoader(),
fruitCakeMachine.getClass().getInterfaces(),
apricotHandler);
cakeMachine.makeCake();
}
}
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
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
而 Java 动态代理只是动态代理的一种实现方式而已,动态代理还有另外一种实现方式,即 CGLib(Code Generation Library)。 通过CGLib实现:
public class ApricotInterceptor implements MethodInterceptor {
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
methodProxy.invokeSuper(o, objects);
System.out.println("adding apricot...");
return o;
}
}
public class CakeShop {
public static void main(String[] args) {
//CGLib动态代理(可以同时给蛋糕、面包等加杏仁)
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(FruitCakeMachine.class);
enhancer.setCallback(new ApricotInterceptor());
FruitCakeMachine fruitCakeMachine = (FruitCakeMachine) enhancer.create();
fruitCakeMachine.makeCake();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 基本原理
# Java动态代理
动态代理的具体步骤:
- 通过实现 InvocationHandler 接口创建自己的调用处理器;
- 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
- 通过 反射机制 获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
- 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。
Java动态代理流程图
# 参考文献
更新时间: 12/2/2022, 12:38:29 AM