JDK动态代理

基于java 8说明

1. JDK动态代理

JDK动态代理由java.lang.reflect.Proxy 类实现,java.lang.reflect.Proxy 对象持有一个 java.lang.reflect.InvocationHandler 对象,而java.lang.reflect.InvocationHandler 对象又持有目标对象;使用时,需要实现InvocationHandler接口(代理的具体逻辑在invoke方法中实现),然后通过java.lang.reflect.Proxy.newProxyInstance等方法生成com.sun.proxy.$Proxy代理对象,来完成对目标对象的调用。

2. 代码示例

package org.example.proxy;

/**
 * 目标接口
 */
public interface RecordLog {

    void add(String log);
}
package org.example.proxy;

import java.time.LocalDateTime;

/**
 * 目标接口实现
 */
public class RecordLogImpl implements RecordLog {
    @Override
    public void add(String log) {
        System.out.println(LocalDateTime.now() + " " + log);
    }
}

package org.example.proxy;

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

/**
 * InvocationHandler实现
 */
public class ProxyHandler<T> implements InvocationHandler {

    private T target;

    public ProxyHandler(T target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 添加自己的操作
        System.out.println("before invoke...");
        Object result = method.invoke(target, args);
        // 添加自己的操作
        System.out.println("after invoke...");
        return result;
    }

    public static void main(String[] args) {
        // 目标对象
        RecordLog target = new RecordLogImpl();

        // InvocationHandler对象
        InvocationHandler handler = new ProxyHandler<>(target);

        // 获取代理对象
        Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                handler);

        // 执行代理
        ((RecordLog) proxy).add("动态代理demo");

        // 输出代理对象的父类和接口
        System.out.println("父类:" + proxy.getClass().getSuperclass());
        for (Class<?> anInterface : proxy.getClass().getInterfaces()) {
            System.out.println("实现接口:" + anInterface);
        }
    }
}

输出

before invoke…
2021-11-08T16:26:51.428 动态代理demo
after invoke…
父类:class java.lang.reflect.Proxy
实现接口:interface org.example.proxy.RecordLog

3. 原理解析

Proxy.newProxyInstance方法会返回一个com.sun.proxy.$Proxy0对象,该对象继承了java.lang.reflect.Proxy类,并且实现了目标接口(JDK动态代理通过实现目标接口的方式来完成对目标对象的代理,所以要求目标对象必须实现接口),生成动态代理类的核心代码在java.lang.reflect.ProxyClassFactory类中。

package java.lang.reflect;

public class Proxy implements java.io.Serializable {

    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h){
       // ...此处省略代码
       
       // 获取动态代理类 com.sun.proxy.$Proxy0
       Class<?> cl = getProxyClass0(loader, intfs);

       try {
            // ...此处省略代码

            final Constructor<?> cons = cl.getConstructor(constructorParams);
            
            // ...此处省略代码

            // 生成代理对象
            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);
        }
    }

    private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) {
        if (interfaces.length > 65535) {
            throw new IllegalArgumentException("interface limit exceeded");
        }
        // 此处调用了java.lang.reflect.WeakCache中的get方法,优先从缓存中获取动态代理类,但最终会调用到ProxyClassFactory.apply方法生成代理类
        return proxyClassCache.get(loader, interfaces);
    }

    // 代理类工厂,用于生成并返回动态代理类
    private static final class ProxyClassFactory
        implements BiFunction<ClassLoader, Class<?>[], Class<?>>
    {
        // ...此处省略代码

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

            // ...此处省略代码
            
            // 生成动态代理类的class文件
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);
            try {
                // defineClass0 是一个native方法,定义了动态代理类
                return defineClass0(loader, proxyName,
                                    proxyClassFile, 0, proxyClassFile.length);
            } catch (ClassFormatError e) {
                throw new IllegalArgumentException(e.toString());
            }
        }
    }
}
package java.lang.reflect;

final class WeakCache<K, P, V> {
    public V get(K key, P parameter) {
        Objects.requireNonNull(parameter);

        expungeStaleEntries();

        Object cacheKey = CacheKey.valueOf(key, refQueue);
        ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
        if (valuesMap == null) {
            ConcurrentMap<Object, Supplier<V>> oldValuesMap
                = map.putIfAbsent(cacheKey,
                                  valuesMap = new ConcurrentHashMap<>());
            if (oldValuesMap != null) {
                valuesMap = oldValuesMap;
            }
        }
        
        // 获取缓存的key值,subKeyFactory为java.lang.reflect.KeyFactory对象
        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
        Supplier<V> supplier = valuesMap.get(subKey);
        Factory factory = null;

        while (true) {
            if (supplier != null) {
                // supplier为java.lang.reflect.Factory对象,此处调用Factory.get()方法获取动态代理类 com.sun.proxy.$Proxy0
                V value = supplier.get();
                if (value != null) {
                    return value;
                }
            }
          
            // 获取java.lang.reflect.Factory对象
            if (factory == null) {
                factory = new Factory(key, parameter, subKey, valuesMap);
            }

            if (supplier == null) {
                supplier = valuesMap.putIfAbsent(subKey, factory);
                if (supplier == null) {
                    supplier = factory;
                }
            } else {
                if (valuesMap.replace(subKey, supplier, factory)) {
                    supplier = factory;
                } else {
                    supplier = valuesMap.get(subKey);
                }
            }
        }
    }

    private final class Factory implements Supplier<V> {
        // ...此处省略代码
        
        @Override
        public synchronized V get() {
            Supplier<V> supplier = valuesMap.get(subKey);
            if (supplier != this) {
                return null;
            }
            
            V value = null;
            try {
                // java.lang.reflect.ProxyClassFactory中的apply方法生成了动态代理类,ProxyClassFactory是Proxy类的内部类
                value = Objects.requireNonNull(valueFactory.apply(key, parameter));
            } finally {
                if (value == null) {
                    valuesMap.remove(subKey, this);
                }
            }
            
            assert value != null;

            CacheValue<V> cacheValue = new CacheValue<>(value);

            if (valuesMap.replace(subKey, this, cacheValue)) {
                reverseMap.put(cacheValue, Boolean.TRUE);
            } else {
                throw new AssertionError("Should not reach here");
            }
            return value;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值