1. 原理,代理模式
代理模式的本质:调用方--->代理方--->实现方。
相对于:调用方--->实现方,降低了调用方与实现方的藕联性,由代理方对实现进行包装,可以包装多个实现方。
1.1 代理模式分为静态代理和动态代理。
其中静态代理需要在代码编写时,编译期提供具体的实现类,不能在程序运行时动态变化代理实现。
其中动态代理常用于Spring的AOP中,有JDK动态代理和CGLIB动态代理,是指程序运行过程中,根据程序的需要动态的生成相关的实现类,也就是说需要代理的类,编译期是不知道的,只有在运行时才确定。
2.静态代理示例
public interface HelloService {
void sayHello(String something);
}
public class HelloServiceImpl implements HelloService {
public void sayHello(String something) {
System.out.println("hello, " + something);
}
}
public class StaticProxy {
//静态代理的不灵活的地方
private HelloService proxyObj;
public StaticProxy (HelloService proxyObj) {
this.proxyObj = proxyObj;
}
public void sayHello(String something) {
proxyObj.sayHello(something);
}
}
如上示例,静态代理必须指定接口名,即对象接口。
3. JDK动态代理示例
public interface HelloService {
void sayHello(String something);
}
public class HelloServiceImpl implements HelloService {
public void sayHello(String something) {
System.out.println("hello, " + something);
}
}
public class DynamicProxy<T> implements InvocationHandler {
//这里是泛型,通配型很强
private T proxyObj;
public DynamicProxy(T proxyObj) {
this.proxyObj = proxyObj;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("----------------------impl myself----------------------");
//反射
return method.invoke(proxyObj, args);
}
}
public static void main(String[] args) {
// 需要代理的对象
HelloService helloService = new HelloServiceImpl();
// 方法反射处理回调
InvocationHandler handler = new DynamicProxy<>(helloService);
//通过 类加载器,接口类对象,反射回调,创建代理对象
HelloService proxyInstance = (HelloService)Proxy.newProxyInstance(handler.getClass().getClassLoader(), helloService
.getClass().getInterfaces(), handler);
//System.out.println(subject.getClass().getName());
proxyInstance.sayHello("ok");
}
----------------------impl myself----------------------
hello, ok
4. JDK动态代理源码分析
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
//克隆代理的实现类的 类对象
final Class<?>[] intfs = interfaces.clone();
//系统安全管理,权限检查管理,比如classloader
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
//检查调用者和代理对象的classloader的权限
//检查包权限
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);//检查是否可以代理
}
/*
* Look up or generate the designated proxy class.
*/
//1. 获取代理类的class对象
Class<?> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
if (sm != null) {
//检查代理的newInstance权限
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
//2. 代理类的构造器
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
//如果修饰符不是public
if (!Modifier.isPublic(cl.getModifiers())) {
//开启权限
//校验权限,设置flag
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
//3. 生成代理类对象
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
* @param loader the class loader to define the proxy class * @param interfaces the list of interfaces for the proxy class * to implement * @param h the invocation handler to dispatch method invocations to
getProxyClass0(ClassLoader loader, Class<?>... interfaces)
/**
* a cache of proxy classes
*/
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
/**
* Generate a proxy class. Must call the checkProxyAccess method
* to perform permission checks before calling this.
*/
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
//这里很畸形,谁没事创建这么多实现类
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
// If the proxy class defined by the given loader implementing
// the given interfaces exists, this will simply return the cached copy;
// otherwise, it will create the proxy class via the ProxyClassFactory
return proxyClassCache.get(loader, interfaces);
}
proxyClassCache.get(loader, interfaces);
本地弱引用缓存
final class WeakCache<K, P, V> {
private final ReferenceQueue<K> refQueue
= new ReferenceQueue<>();
// the key type is Object for supporting null key
private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
= new ConcurrentHashMap<>();
private final ConcurrentMap<Supplier<V>, Boolean> reverseMap
= new ConcurrentHashMap<>();
private final BiFunction<K, P, ?> subKeyFactory;
private final BiFunction<K, P, V> valueFactory;
private void expungeStaleEntries() {
CacheKey<K> cacheKey;
while ((cacheKey = (CacheKey<K>)refQueue.poll()) != null) {
//移除引用队列的key缓存
cacheKey.expungeFrom(map, reverseMap);
}
}
private static final class CacheKey<K> extends WeakReference<K> {
// a replacement for null keys
private static final Object NULL_KEY = new Object();
static <K> Object valueOf(K key, ReferenceQueue<K> refQueue) {
return key == null
// null key means we can't weakly reference it,
// so we use a NULL_KEY singleton as cache key
? NULL_KEY
// non-null key requires wrapping with a WeakReference
: new CacheKey<>(key, refQueue);
}
private final int hash;
private CacheKey(K key, ReferenceQueue<K> refQueue) {
super(key, refQueue);
this.hash = System.identityHashCode(key); // compare by identity
}
@Override
public int hashCode() {
return hash;
}
@Override
public boolean equals(Object obj) {
K key;
return obj == this ||
obj != null &&
obj.getClass() == this.getClass() &&
// cleared CacheKey is only equal to itself
(key = this.get()) != null &&
// compare key by identity
key == ((CacheKey<K>) obj).get();
}
void expungeFrom(ConcurrentMap<?, ? extends ConcurrentMap<?, ?>> map,
ConcurrentMap<?, Boolean> reverseMap) {
// removing just by key is always safe here because after a CacheKey
// is cleared and enqueue-ed it is only equal to itself
// (see equals method)...
ConcurrentMap<?, ?> valuesMap = map.remove(this);
// remove also from reverseMap if needed
if (valuesMap != null) {
for (Object cacheValue : valuesMap.values()) {
reverseMap.remove(cacheValue);
}
}
}
}
public V get(K key, P parameter) {
Objects.requireNonNull(parameter);
//清理已被GC回收的弱引用key的value,避免内存泄漏
expungeStaleEntries();
//classloader 和 refQueue构造一个CacheKey弱引用作为map的key
//proxy传入的key是classloader,parameter是接口的实现类class[]数组
Object cacheKey = CacheKey.valueOf(key, refQueue);
// lazily install the 2nd level valuesMap for the particular cacheKey
ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
//有值使用,没有new
if (valuesMap == null) {
ConcurrentMap<Object, Supplier<V>> oldValuesMap
= map.putIfAbsent(cacheKey,
valuesMap = new ConcurrentHashMap<>());
if (oldValuesMap != null) {
valuesMap = oldValuesMap;
}
}
// create subKey and retrieve the possible Supplier<V> stored by that
// subKey from valuesMap
//subKey的来源,很关键,此处的subKey也是弱引用的
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
Supplier<V> supplier = valuesMap.get(subKey);
Factory factory = null;
//自旋赋值
while (true) {
if (supplier != null) {
// supplier might be a Factory or a CacheValue<V> instance
//获取的值可能是Factory,也可能是实例CacheValue
V value = supplier.get();//如果是factory,get方法就会创建CacheValue;CacheValue就会直接获取值value
if (value != null) {
return value;
}
}
// else no supplier in cache
// or a supplier that returned null (could be a cleared CacheValue
// or a Factory that wasn't successful in installing the CacheValue)
// lazily construct a Factory
//这里初次循环一定为null,目的是上一步获取不到值工厂创建
if (factory == null) {
//factory初始化
factory = new Factory(key, parameter, subKey, valuesMap);
}
if (supplier == null) {
//初始化子map的value值
supplier = valuesMap.putIfAbsent(subKey, factory);
if (supplier == null) {
// successfully installed Factory
supplier = factory;
}
// else retry with winning supplier
} else {
//这里是对象存在,value值为null,更新值
if (valuesMap.replace(subKey, supplier, factory)) {
// successfully replaced
// cleared CacheEntry / unsuccessful Factory
// with our Factory
supplier = factory;
} else {
//刷新值
// retry with current supplier
supplier = valuesMap.get(subKey);
}
}
}
}
subKeyFactory.apply(key, parameter)
/**
* A function that maps an array of interfaces to an optimal key where
* Class objects representing interfaces are weakly referenced.
*/
private static final class KeyFactory
implements BiFunction<ClassLoader, Class<?>[], Object>
{
@Override
public Object apply(ClassLoader classLoader, Class<?>[] interfaces) {
switch (interfaces.length) {
case 1: return new Key1(interfaces[0]); // the most frequent
case 2: return new Key2(interfaces[0], interfaces[1]);
case 0: return key0;
default: return new KeyX(interfaces);
}
}
}
当代理的实现类class[]的数量超过0,0就代表没有代理对象,没意义
private static final class Key1 extends WeakReference<Class<?>> {
private final int hash;
private static final class Key2 extends WeakReference<Class<?>> {
private final int hash;
private final WeakReference<Class<?>> ref2;
private static final class KeyX {
private final int hash;
private final WeakReference<Class<?>>[] refs;
KeyX(Class<?>[] interfaces) {
hash = Arrays.hashCode(interfaces);
refs = (WeakReference<Class<?>>[])new WeakReference<?>[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
refs[i] = new WeakReference<>(interfaces[i]);
}
}
可以看出是hash和代理的实现类class[]弱引用的引用对象。
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() { // serialize access
// re-check
Supplier<V> supplier = valuesMap.get(subKey);
if (supplier != this) {
// something changed while we were waiting:
// might be that we were replaced by a CacheValue
// or were removed because of failure ->
// return null to signal WeakCache.get() to retry
// the loop
return null;
}
// else still us (supplier == this)
// create new value
V value = null;
try {
//创建值,生成代理类
value = Objects.requireNonNull(valueFactory.apply(key, parameter));
} finally {
//移除值,便于GC,清理弱引用
if (value == null) { // remove us on failure
valuesMap.remove(subKey, this);
}
}
// the only path to reach here is with non-null value
assert value != null;
// wrap value with CacheValue (WeakReference)
//这就是子map的值cacheValue
CacheValue<V> cacheValue = new CacheValue<>(value);
// put into reverseMap
reverseMap.put(cacheValue, Boolean.TRUE);
// try replacing us with CacheValue (this should always succeed)
更新factory为cacheValue
if (!valuesMap.replace(subKey, this, cacheValue)) {
throw new AssertionError("Should not reach here");
}
// successfully replaced us with new CacheValue -> return the value
// wrapped by it
return value;
}
}
valueFactory.apply(key, parameter)
//此处生成了字节码类$Proxy0,1,2,3,动态加载
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
// prefix for all proxy class names
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);
for (Class<?> intf : interfaces) {
/*
* Verify that the class loader resolves the name of this
* interface to the same Class object.
*/
Class<?> interfaceClass = null;
try {
//反射class
interfaceClass = Class.forName(intf.getName(), false, loader);
} catch (ClassNotFoundException e) {
}
if (interfaceClass != intf) {
throw new IllegalArgumentException(
intf + " is not visible from class loader");
}
/*
* Verify that the Class object actually represents an
* interface.
*/
//是否是接口实现类接口
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(
interfaceClass.getName() + " is not an interface");
}
/*
* Verify that this interface is not a duplicate.
*/
//接口的实现类重复
if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
throw new IllegalArgumentException(
"repeated interface: " + interfaceClass.getName());
}
}
String proxyPkg = null; // package to define proxy class in
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
/*
* Record the package of a non-public proxy interface so that the
* proxy class will be defined in the same package. Verify that
* all non-public proxy interfaces are in the same package.
验证所有非公共代理接口是同一个包
*/
for (Class<?> intf : interfaces) {
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) {//只处理非public接口,得到非public接口的包名
accessFlags = Modifier.FINAL;
String name = intf.getName();
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
if (proxyPkg == null) {
proxyPkg = pkg;
} else if (!pkg.equals(proxyPkg)) {
throw new IllegalArgumentException(
"non-public interfaces from different packages");
}
}
}
if (proxyPkg == null) {
// if no non-public proxy interfaces, use com.sun.proxy package
//默认包名,public接口都会使用
//public static final String PROXY_PACKAGE = "com.sun.proxy";
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
/*
* Choose a name for the proxy class to generate.
atomic保证自增原子性
*/
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;//代理类名称包名$Proxy+0,1,2,3......
/*
* Generate the specified proxy class.
*/
//生成代理类字节码
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
//字节码loader进内存,加载代理类对象
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
/*
* A ClassFormatError here means that (barring bugs in the
* proxy class generation code) there was some other
* invalid aspect of the arguments supplied to the proxy
* class creation (such as virtual machine limitations
* exceeded).
*/
throw new IllegalArgumentException(e.toString());
}
}
}
ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags)
//此处默认false,需要手工设置才会写文件
private static final boolean saveGeneratedFiles = (Boolean)AccessController.doPrivileged(new GetBooleanAction("sun.misc.ProxyGenerator.saveGeneratedFiles"));
public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) {
ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);
//生成字节码
final byte[] var4 = var3.generateClassFile();
//saveGeneratedFiles为true,写文件,默认是不写文件的,动态classloader加载
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));
Files.createDirectories(var3);
var2 = var3.resolve(var0.substring(var1 + 1, var0.length()) + ".class");
} else {
var2 = Paths.get(var0 + ".class");
}
Files.write(var2, var4, new OpenOption[0]);
return null;
} catch (IOException var4x) {
throw new InternalError("I/O exception saving generated file: " + var4x);
}
}
});
}
return var4;
}
仅当VM参数设置sun.misc.ProxyGenerator.saveGeneratedFiles才会写文件
-Dsun.misc.ProxyGenerator.saveGeneratedFiles=true
也可以调试发现
反编译
public final void sayHello(String paramString)
{
try
{
this.h.invoke(this, m3, new Object[] { paramString });
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
实现的方式使用通过InvocationHandler实现类(Proxy的参数传入)的invoke方法发起调用。
动态生成了接口的实现类
generateClassFile()
private byte[] generateClassFile() {
//基本方法
this.addProxyMethod(hashCodeMethod, Object.class);
this.addProxyMethod(equalsMethod, Object.class);
this.addProxyMethod(toStringMethod, Object.class);
Class[] var1 = this.interfaces;
int var2 = var1.length;
int var3;
Class var4;
for(var3 = 0; var3 < var2; ++var3) {
var4 = var1[var3];
Method[] var5 = var4.getMethods();
int var6 = var5.length;
for(int var7 = 0; var7 < var6; ++var7) {
Method var8 = var5[var7];
//接口方法
this.addProxyMethod(var8, var4);
}
}
Iterator var11 = this.proxyMethods.values().iterator();
List var12;
while(var11.hasNext()) {
var12 = (List)var11.next();
//返回类型检查
checkReturnTypes(var12);
}
Iterator var15;
try {
//构造器
this.methods.add(this.generateConstructor());
var11 = this.proxyMethods.values().iterator();
while(var11.hasNext()) {
var12 = (List)var11.next();
var15 = var12.iterator();
while(var15.hasNext()) {
ProxyGenerator.ProxyMethod var16 = (ProxyGenerator.ProxyMethod)var15.next();
//类属性
this.fields.add(new ProxyGenerator.FieldInfo(var16.methodFieldName, "Ljava/lang/reflect/Method;", 10));
//方法
this.methods.add(var16.generateMethod());
}
}
//静态初始化
this.methods.add(this.generateStaticInitializer());
} catch (IOException var10) {
throw new InternalError("unexpected I/O Exception", var10);
}
if (this.methods.size() > 65535) {
throw new IllegalArgumentException("method limit exceeded");
} else if (this.fields.size() > 65535) {
throw new IllegalArgumentException("field limit exceeded");
} else {
//常量池索引
this.cp.getClass(dotToSlash(this.className));
this.cp.getClass("java/lang/reflect/Proxy");
var1 = this.interfaces;
var2 = var1.length;
for(var3 = 0; var3 < var2; ++var3) {
var4 = var1[var3];
this.cp.getClass(dotToSlash(var4.getName()));
}
//锁定常量池,只读
this.cp.setReadOnly();
ByteArrayOutputStream var13 = new ByteArrayOutputStream();
DataOutputStream var14 = new DataOutputStream(var13);
//写字节码
try {
var14.writeInt(-889275714);
var14.writeShort(0);
var14.writeShort(49);
this.cp.write(var14);
var14.writeShort(this.accessFlags);
var14.writeShort(this.cp.getClass(dotToSlash(this.className)));
var14.writeShort(this.cp.getClass("java/lang/reflect/Proxy"));
var14.writeShort(this.interfaces.length);
Class[] var17 = this.interfaces;
int var18 = var17.length;
//字节码写继承实现
for(int var19 = 0; var19 < var18; ++var19) {
Class var22 = var17[var19];
var14.writeShort(this.cp.getClass(dotToSlash(var22.getName())));
}
var14.writeShort(this.fields.size());
var15 = this.fields.iterator();
//字节码写属性
while(var15.hasNext()) {
ProxyGenerator.FieldInfo var20 = (ProxyGenerator.FieldInfo)var15.next();
var20.write(var14);
}
var14.writeShort(this.methods.size());
var15 = this.methods.iterator();
//字节码写方法
while(var15.hasNext()) {
ProxyGenerator.MethodInfo var21 = (ProxyGenerator.MethodInfo)var15.next();
var21.write(var14);
}
var14.writeShort(0);
//字节码
return var13.toByteArray();
} catch (IOException var9) {
throw new InternalError("unexpected I/O Exception", var9);
}
}
}
public short getClass(String var1) {
short var2 = this.getUtf8(var1);
return this.getIndirect(new ProxyGenerator.ConstantPool.IndirectEntry(7, var2));
}
5. 总结
动态代理生成过程,取缓存,缓存取不到就动态生成字节码,加载进内存
缓存cacheMap的classloader的弱引用作为key,value是map
而map是以class[]的用引用做key,value是值为动态生成的代理类class<?> 的弱引用CacheValue。