【JAVA】动态代理

动态代理

代理模式包含三个角色:

  1. Subject主题对象:一般是一个接口,定义一些方法。
  2. RealSubject 具体的主题实现对象:实现Subject中定义的方法。
  3. Proxy 代理对象:Proxy中包含一个RealSubject的引用,由代理对象实现RealSubject方法的调用。

Subject

1
2
3
public interface Subject {
void execute();
}

RealSubject

1
2
3
4
5
6
public class RealSubject implements Subject {
@Override
public void execute() {
System.out.println("realsubject方法执行");
}
}

代理对象

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 ProxyInvocationHandler implements InvocationHandler {

/**
* 代理的目标对象,也就是RealSubject
*/
private Object target;

/**
* 构造函数
*/
public ProxyInvocationHandler(Object target){
this.target = target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始执行方法:" + method.getName());
// 执行RealSubject中的方法
Object result = method.invoke(target, args);
System.out.println("结束执行方法:" + method.getName());
return null;
}

public Object getProxy() {
// 创建代理对象
return Proxy.newProxyInstance(Thread.currentThread()
.getContextClassLoader(), target.getClass().getInterfaces(), this);
}
}

测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class ProxyTest {
public static void main(String[] args) {
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
// 创建实际的对象
Subject subject = new RealSubject();
// 创建InvocationHandler
ProxyInvocationHandler invocationHandler = new ProxyInvocationHandler(subject);
// 获取代理对象
Subject proxy = (Subject) invocationHandler.getProxy();
// 执行方法
proxy.execute();
}
}

运行结果:

1
2
3
开始执行方法:execute
realsubject方法执行
结束执行方法:execute

动态代理实现原理

在ProxyInvocationHandler中可以看到通过Proxy创建了一个代理对象,那么接下来就进入到Proxy中,看一下是如何创建代理对象的:

1
2
3
// 创建代理对象
return Proxy.newProxyInstance(Thread.currentThread()
.getContextClassLoader(), target.getClass().getInterfaces(), this);

Proxy

在Proxy中newProxyInstance方法创建代理对象的时候,传入了类加载器、需要代理的Subject对象以及InvocationHandler:

  1. 根据类加载器和需要代理的Subject对象生成代理类的class
  2. 根据生成的代理类的class信息,通过构造器创建代理对象,并将InvocationHandler传入
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
public class Proxy implements java.io.Serializable {
// 创建代理对象
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h) throws IllegalArgumentException {
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
// 获取代理类的class
Class<?> cl = getProxyClass0(loader, intfs);
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
// 获取构造器
final Constructor<?> cons = cl.getConstructor(constructorParams);
// InvocationHandler
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
// 通过构造器创建代理对象,并将InvocationHandler传入
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
//...
}
}
}
生成代理类的class

getProxyClass0中首先会进行边界检查,然后根据加载器和需要代理的Subject信息从proxyClassCache缓存中获取生成的代理类的calss

,具体的实现在WeakCache的get方法中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 代理类的缓存
*/
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

/**
* 生成代理类的class
*/
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
// 边界检查
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
// 从proxyClassCache中获取class
return proxyClassCache.get(loader, interfaces);
}
WeakCache

WeakCache的get方法中如果根据缓存key获取对象为空,会创建一个Factory对象赋值给Supplier,Factory是WeakCache的一个内部类,它实现了Supplier接口,然后调用Supplier的get方法来生成代理类的class,接下来进入到Factory的get方法中:

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
final class WeakCache<K, P, V> {
// 获取class
public V get(K key, P parameter) {
Objects.requireNonNull(parameter);
expungeStaleEntries();
// 获取缓存key
Object cacheKey = CacheKey.valueOf(key, refQueue);
// 根据key获取对象
ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
// 如果为空
if (valuesMap == null) {
// 创建一个ConcurrentMap
ConcurrentMap<Object, Supplier<V>> oldValuesMap
= map.putIfAbsent(cacheKey,
valuesMap = new ConcurrentHashMap<>());
if (oldValuesMap != null) {
valuesMap = oldValuesMap;
}
}
// 创建subKey
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
Supplier<V> supplier = valuesMap.get(subKey);
Factory factory = null;
while (true) {
if (supplier != null) {
// 调用get方法获取class
V value = supplier.get();
if (value != null) {
return value;
}
}
// 如果为空,创建Factory
if (factory == null) {
factory = new Factory(key, parameter, subKey, valuesMap);
}
// 如果supplier为null
if (supplier == null) {
supplier = valuesMap.putIfAbsent(subKey, factory);
if (supplier == null) {
// 将factory赋值给supplier
supplier = factory;
}
} else {
if (valuesMap.replace(subKey, supplier, factory)) {
supplier = factory;
} else {
// retry with current supplier
supplier = valuesMap.get(subKey);
}
}
}
}
}
Factory

Factory是WeakCache的一个内部类,它实现了Supplier接口,在get方法中,又调用了valueFactory的apply方法创建class,valueFactory是WeakCache的一个成员变量,在WeakCache的构造函数中可以看到传入了valueFactory对象进行初始化,那么接下来就需要回到Proxy类中,看一下如何实例化WeakCache的:

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
final class WeakCache<K, P, V> {

private final BiFunction<K, P, V> valueFactory;

public WeakCache(BiFunction<K, P, ?> subKeyFactory,
BiFunction<K, P, V> valueFactory) {
this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
// 初始化
this.valueFactory = Objects.requireNonNull(valueFactory);
}

// Factory
private final class Factory implements Supplier<V> {

private final K key;
private final P parameter;
private final Object subKey;
private final ConcurrentMap<Object, Supplier<V>> valuesMap;

Factory(K key, P parameter, Object subKey,
ConcurrentMap<Object, Supplier<V>> valuesMap) {
this.key = key;
this.parameter = parameter;
this.subKey = subKey;
this.valuesMap = valuesMap;
}

@Override
public synchronized V get() {
//
Supplier<V> supplier = valuesMap.get(subKey);
if (supplier != this) {
return null;
}

V value = null;
try {
// 调用valueFactory的apply方法创建class
value = Objects.requireNonNull(valueFactory.apply(key, parameter));
} finally {
if (value == null) { // remove us on failure
valuesMap.remove(subKey, this);
}
}

......

return value;
}
}
}
ProxyClassFactory

Proxy中WeakCache初始化的时候使用的是ProxyClassFactory类型的factory:

1
2
3
4
5
6
7
public class Proxy implements java.io.Serializable {  
/**
* WeakCache初始化
*/
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
}

所以调用valueFactory的apply方法的时候会进入到ProxyClassFactory的apply方法,在apply方法中会通过ProxyGenerator动态生成代理类并加载类,然后将实例化的代理类返回:

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
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
// 前缀
private static final String proxyClassNamePrefix = "$Proxy";

// next number to use for generation of unique proxy class names
private static final AtomicLong nextUniqueNumber = new AtomicLong();

@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {

Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
......

long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;

/*
* 生成代理类
*/
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
// 加载代理,并返回对象
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {

throw new IllegalArgumentException(e.toString());
}
}
}
ProxyGenerator

ProxyGenerator是Proxy的一个内部类,用于动态生成class:

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
 private static final class ProxyClassFactory implements BiFunction<ClassLoader, Class<?>[], Class<?>> {  
public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) {
ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);
// 生成class
final byte[] var4 = var3.generateClassFile();
// 是否保存到文件,如果开启了之后,运行程序之后会在包下面生成class文件
if(saveGeneratedFiles) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
try {
int var1 = var0.lastIndexOf(46);
Path var2;
if(var1 > 0) {
Path var3 = Paths.get(var0.substring(0, var1).replace('.', File.separatorChar), new String[0]);
Files.createDirectories(var3, new FileAttribute[0]);
var2 = var3.resolve(var0.substring(var1 + 1, var0.length()) + ".class");
} else {
var2 = Paths.get(var0 + ".class", new String[0]);
}

Files.write(var2, var4, new OpenOption[0]);
return null;
} catch (IOException var4x) {
throw new InternalError("I/O exception saving generated file: " + var4x);
}
}
});
}
return var4;
}
}
代理类的生成

由于设置了sun.misc.ProxyGenerator.saveGeneratedFiles为true,所以可以在包下面看到生成的代理类$Proxy0:

  1. 它继承了Proxy并实现了Subject,并且在构造函数中需要传入InvocationHandler对象
  2. 当执行$Proxy0中的execute方法时,实际上调用的是InvocationHandler的invoke方法
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

package com.sun.proxy;

import com.example.demo.bean.Subject;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

// 动态生成了一个$Proxy0类,它继承了Proxy并实现了Subject
public final class $Proxy0 extends Proxy implements Subject {
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m0;
// 传入InvocationHandler对象
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}

public final boolean equals(Object var1) throws {
try {
return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue();
} 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);
}
}

// Subject的execute方法
public final void execute() throws {
try {
// 调用了InvocationHandler的invoke方法
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}

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

static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m3 = Class.forName("com.example.demo.bean.Subject").getMethod("execute", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}

总结

JDK的动态代理实现原理是在运行中动态生成代理类,这个代理类实现了Subject接口,在对代理类进行实例化的时候,需要传入InvocationHandler,当调用代理类的方法时,会执行InvocationHandler的invoke方法,从而完成代理功能。

参考

【拉勾教育】Dubbo源码解读与实战-代理模式与常见实现