美文网首页
动态代理

动态代理

作者: Java旅行者 | 来源:发表于2017-08-27 20:31 被阅读0次

    Java 中的动态代理

    源码分析实现原理的过程

    http://blog.csdn.net/bluetjs/article/details/52263410

    步骤

    1. 必须要有一个接口, Subject

    2. 有一个类实现接口,RealSubject

    3. 实现 InvocationHandler 接口,书写代理类的逻辑

    4. 通过 Proxy.newProxyInstance 方法创建代理对象

    代码:

    package com.interview.reflect;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyTest {
    
        public static void main(String[] args) {
            Subject s = new RealSubject();
            Subject subject = (Subject) Proxy.newProxyInstance(s.getClass().getClassLoader(),
            s.getClass().getInterfaces(), new ProxyHandler<Subject>(s));
            subject.method();
            subject.dream();
    
        }
    }
    
    interface Subject {
    
        void method();
    
        void dream();
    
    }
    
    class RealSubject implements Subject {
    
        @Override
        public void method() {
            System.out.println("method run...");
        }
    
        @Override
        public void dream() {
            System.out.println("dream come true...");
        }
    }
    
    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 method process<<<<");
            method.invoke(target, args);
            System.out.println("after method invoke process>>>>>>");
            return target;
        }
    }
    

    运行结果

    before invoke method process
    method run...
    after method invoke process
    before invoke method process
    dream come true...
    after method invoke process

    底层实现

    JDK提供了sun.misc.ProxyGenerator.generateProxyClass(String proxyName,class[] interfaces) 底层方法来产生动态代理类的字节码,这是 proxy 的底层实现

    仔细观察可以看出生成的动态代理类有以下特点:

    1. 继承自 java.lang.reflect.Proxy,实现了目标类需要实现的接口

    2. 类中的所有方法都是 final 的

    3. 所有的方法功能的实现都统一调用了 InvocationHandler 的 invoke() 方法

    cglib 的动态代理

    Java 的动态代理的缺点是类必须要实现接口,如果没有实现接口则无法产生代理。为了应对这种情况,于是就产生了 cglib 的动态代理。

    cglib 创建某个类A的动态代理类的模式是

    1. 查找A上的所有非final 的public类型的方法定义

    2. 将这些方法的定义转换成字节码

    3. 将组成的字节码转换成相应的代理的class对象

    4. 实现 MethodInterceptor接口,用来处理 对代理类上所有方法的请求(这个接口和JDK动态代理InvocationHandler的功能和角色是一样的)

    其他的字节码工具

    javaassist,asm

    相关文章

      网友评论

          本文标题:动态代理

          本文链接:https://www.haomeiwen.com/subject/zgeidxtx.html