本文是转载,原博主地址http://rejoy.iteye.com/blog/1627405

java 动态代理实例

MyInvocationHandler.java-实现自己的InvocationHandler

public class MyInvocationHandler implements InvocationHandler {
    //目标对象(代理的真实对象)
    private Object target;

    /**
     * 构造方法
     *
     * @param target 目标对象
     */
    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    /**
     * 执行目标对象的方法
     *
     * @param proxy
     * @param method
     * @param args
     * @return
     * @throws Throwable
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 在目标对象的方法执行之前简单的打印一下
        System.out.println("------------------before------------------");

        // 执行目标对象的方法
        Object result = method.invoke(target, args);

        // 在目标对象的方法执行之后简单的打印一下
        System.out.println("-------------------after------------------");

        return result;
    }

    /**
     * 获取目标对象的代理对象
     *
     * @return 代理对象
     */
    public Object getProxy() {
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                target.getClass().getInterfaces(), this);
    }
}

UserService.java-目标对象实现的接口,用JDK来生成代理对象一定要实现一个接口 

public interface UserService {
    /**
     * 目标方法
     */
    void add();
}

UserServiceImpl.java-目标对象

public class UserServiceImpl implements UserService {
    public void add() {
        System.out.println("add");
    }
}

ProxyTest.java-测试类

public class ProxyTest {
    public static void main(String[] args) {
        // 实例化目标对象
        UserService userService = new UserServiceImpl();

        // 实例化InvocationHandler
        MyInvocationHandler invocationHandler = new MyInvocationHandler(userService);

        // 根据目标对象生成代理对象
        UserService proxy = (UserService) invocationHandler.getProxy();

        System.out.println(proxy.getClass().getName());

        // 调用代理对象的方法
        proxy.add();
    }
}

输出

com.sun.proxy.$Proxy0
------------------before------------------
add
-------------------after------------------

既然生成代理对象是用的Proxy类的静态方newProxyInstance,那么我们就去它的源码里看一下它到底都做了些什么? 

 public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
            throws IllegalArgumentException
    {
        //判断InvocationHandler是否为空
        Objects.requireNonNull(h);
        //拷贝接口数组
        final Class<?>[] intfs = interfaces.clone();
        final SecurityManager sm = System.getSecurityManager();
        //校验代理类的访问问权限 具体的请去查java安全管理器。
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }

        /*
         * Look up or generate the designated proxy class.
         */
        //查找或生成指定的代理类。
        Class<?> cl = getProxyClass0(loader, intfs);

        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }
            //获取代理类构造函数
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            //构造函数不是public,则设置当前构造函数为访问权限
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
            // 生成代理类的实例并把MyInvocationHandler的实例传给它的构造方法
            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);
        }
    }

  我们再进去getProxyClass0方法看一下

 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)方法看一下

public V get(K key,P parameter){
    //parameter不能weinull
    Objects.requireNonNull(parameter);
    //删除老节点
    expungeStaleEntries();

    Object cacheKey=CacheKey.valueOf(key,refQueue);

    // lazily install the 2nd level valuesMap for the particular cacheKey
    ConcurrentMap<Object, Supplier<V>>valuesMap=map.get(cacheKey);
    if(valuesMap==null){
        //添加cacheKey - ConcurrentMap<Object, Supplier<V>对象到map中
        ConcurrentMap<Object, Supplier<V>>oldValuesMap=map.putIfAbsent(cacheKey,valuesMap=new ConcurrentHashMap<>());
        if(oldValuesMap!=null){
            valuesMap=oldValuesMap;
        }
    }

    //利用subKeyFactory生成subKey
    Object subKey=Objects.requireNonNull(subKeyFactory.apply(key,parameter));
    //获取valuesMap中subKey所对应的值,此时为cachevalue <V>实例(步骤1:cachevalue <V>实例的来源)
    Supplier<V> supplier=valuesMap.get(subKey);
    Factory factory=null;

    while(true){
        if(supplier!=null){
        //步骤1:supplier可能是一个工厂对象或一个cachevalue <V>实例
        V value=supplier.get();
        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
    if(factory==null){
        //构造一个工厂对象(步骤1:工厂对象的来源)
        factory=new Factory(key,parameter,subKey,valuesMap);
    }
    //
    if(supplier==null){
    //factory添加在valuesMap中
        supplier=valuesMap.putIfAbsent(subKey,factory);
        if(supplier==null){
            // 添加成功,则factory赋值给supplier,此时supplier为一个工厂对象
            supplier=factory;
        }
    // else retry with winning supplier
    //失败则重试
    }else{
        //将valuesMap中subKey所对应的值替换为factory
        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);
        }
    }
}

此时supplier返回一个工厂对象factory,并调用factory.get()方法

@Override
public synchronized V get() { // serialize access
    //校验是否为同一个
    Supplier<V> supplier = valuesMap.get(subKey);
    if (supplier != this) {
        return null;
    }
    //创建一个新值
    V value = null;
    try {
        //调用valueFactory的applay方法生成一个新值
        value = Objects.requireNonNull(valueFactory.apply(key, parameter));
    } finally {
        if (value == null) { //如果生成失败,从valuesMap中删除值
            valuesMap.remove(subKey, this);
        }
    }
    // the only path to reach here is with non-null value
    assert value != null;

    // wrap value with CacheValue (WeakReference)
    CacheValue<V> cacheValue = new CacheValue<>(value);

    //尝试更换我们cachevalue(这应该总是成功的)此时
    if (valuesMap.replace(subKey, this, cacheValue)) {
        // 放在reversemap
        reverseMap.put(cacheValue, Boolean.TRUE);
    } else {
        throw new AssertionError("Should not reach here");
    }
    //成功取代当前工厂对象为一个新的CacheValue(包裹着我们的需要对象:代理类)
    return value;
}

进入valueFactory.apply(key, parameter)方法

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

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

        //验证intf接口类Class对象是否为给定的classloder解析的
        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");
        }
        //验证类对象是否为接口
        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;
    //定义代理类的修饰符:public和final类型
    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修饰符
            //则定义代理类的修饰符符:final
            accessFlags = Modifier.FINAL;
            //获取接口类名称,如:com.text.MyInterface
            String name = intf.getName();
            int n = name.lastIndexOf('.');
            //获取包名,如:com.text
            String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
            if (proxyPkg == null) {
                //获取包名称
                proxyPkg = pkg;
            } else if (!pkg.equals(proxyPkg)) { //interfaces含有来自不同包的非公共接口,抛错
                throw new IllegalArgumentException(
                "non-public interfaces from different packages");
            }
        }
    }

    if (proxyPkg == null) {
        //如果没有非公开的代理接口,使用com.sun.proxy作为包名称
        proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
    }

    //选择要生成的代理类的名称。
    long num = nextUniqueNumber.getAndIncrement();
    String proxyName = proxyPkg + proxyClassNamePrefix + num;

    //真正生成指定的代理类字节码的地方
    byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
    proxyName, interfaces, accessFlags);
    try {
        //生成Calss对象
        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()方法。

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,则会把所生成的代理类的字节码保存到硬盘上
    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;
}

 

10-04 11:33