0%

Java动态代理

Java动态代理

参考文档: https://www.cnblogs.com/whirly/p/10154887.html

本文将介绍的Java动态代理与设计模式中的代理模式有关,什么是代理模式呢?

代理模式:给某一个对象提供一个代理,并由代理对象来控制对真实对象的访问。代理模式是一种结构型设计模式。

代理模式角色分为 3 种:

Subject(抽象主题角色):定义代理类和真实主题的公共对外方法,也是代理类代理真实主题的方法;

RealSubject(真实主题角色):真正实现业务逻辑的类;

Proxy(代理主题角色):用来代理和封装真实主题;

代理模式的结构比较简单,其核心是代理类,为了让客户端能够一致性地对待真实对象和代理对象,在代理模式中引入了抽象层

代理模式类图

代理模式按照职责(使用场景)来分类,至少可以分为以下几类:1、远程代理。 2、虚拟代理。 3、Copy-on-Write 代理。 4、保护(Protect or Access)代理。 5、Cache代理。 6、防火墙(Firewall)代理。 7、同步化(Synchronization)代理。 8、智能引用(Smart Reference)代理等等。

如果根据字节码的创建时机来分类,可以分为静态代理和动态代理:

所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和真实主题角色的关系在运行前就确定了。
而动态代理的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以在运行前并不存在代理类的字节码文件

接下来我们使用代码实现动态代理

被代理类接口

1
2
3
4
public interface Client {
void getUp();
void sleep();
}

被代理类实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class ClientImpl implements Client{
private String name;
public ClientImpl(String name) {
this.name = name;
}

@Override
public void sleep() {
System.out.println(name+"睡觉了");
}

public void getUp(){
System.out.println(name+"起床了");
}
}

逻辑控制器

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
/**
* 逻辑处理器
*/
import java.lang.reflect.*;

public class ClientProxy implements InvocationHandler {

//被代理类
private Object target;
//代理类
private Object proxy;
//被代理类属性
private String name;

public Object getProxy() {
return proxy;
}

//改造方法
public ClientProxy(Object _target) throws NoSuchFieldException, IllegalAccessException {

target=_target;
Class<?> c = _target.getClass();
//被代理类加载器
ClassLoader classLoader = c.getClassLoader();
//被代理类实现接口
Class<?>[] interfaces = c.getInterfaces();
//创建代理类
this.proxy = Proxy.newProxyInstance(classLoader, interfaces, this);
//获取被代理类的属性
Field _name = c.getDeclaredField("name");
_name.setAccessible(true);
this.name = (String)_name.get(target);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
xl();
//通过反射执行方法
Object invoke = method.invoke(target, args);
xz();
//返回结果集
return invoke;
}

public void xl() throws NoSuchFieldException, IllegalAccessException {
System.out.println(name+"洗脸刷牙");
}
public void xz(){
System.out.println(name+"洗脸刷牙洗澡");
}
}

main方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Test {

public static void main(String[] args) {
//被代理对象
ClientImpl target=new ClientImpl("李四");
ClientProxy clientProxy= null;
try {
//创建逻辑控制器 其内部生成代理类
clientProxy = new ClientProxy(target);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//获取代理对象 对其类型强制转换
Client proxy=(Client) clientProxy.getProxy();
//调用方法
proxy.getUp();

//将代理类io流写到磁盘
ProxyUtils.generateClassFile(clientProxy.getClass(), "ClientImplProxy");
}
}

ProxyUtils

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
public class ProxyUtils {
/**
* 将根据类信息动态生成的二进制字节码保存到硬盘中,默认的是clazz目录下
* params: clazz 需要生成动态代理类的类
* proxyName: 为动态生成的代理类的名称
*/
public static void generateClassFile(Class clazz, String proxyName) {
// 根据类信息和提供的代理类名称,生成字节码
byte[] classFile = ProxyGenerator.generateProxyClass(proxyName, clazz.getInterfaces());
//获取路径
String paths = clazz.getResource(".").getPath();
System.out.println(paths);
FileOutputStream out = null;
try {
//保留到硬盘中
out = new FileOutputStream(paths + proxyName + ".class");
out.write(classFile);
out.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

反编译后的代理类

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
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class ClientImplProxy extends Proxy implements InvocationHandler {
//每一个方法
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m0;


public ClientImplProxy(InvocationHandler var1) throws {
super(var1);
}

public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}

public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}


public final Object invoke(Object var1, Method var2, Object[] var3) throws Throwable {
//调用其逻辑控制器的invoke方法
return (Object)super.h.invoke(this, m3, new Object[]{var1, var2, var3});
}

public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}

static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m3 = Class.forName("java.lang.reflect.InvocationHandler").getMethod("invoke", Class.forName("java.lang.Object"), Class.forName("java.lang.reflect.Method"), Class.forName("[Ljava.lang.Object;"));
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}

动态代理逻辑图

img

文章作者:xpp011

发布时间:2021年11月14日 - 23:11

原始链接:http://xpp011.cn/2021/11/14/abd111cb.html

许可协议: 转载请保留原文链接及作者。