Java动态代理

作者: 离别刀 | 来源:发表于2018-05-22 16:30 被阅读0次
    08145526.png

    说起动态代理,大家可能都很熟悉,个人自认为动态代理最大的优势就是对原对象无任何侵入的情况下,可以对该对象中的某一方法进行扩展。体现最直接就是Spring中当的Aop了,还有Mybatis中的interface。
    动态代理可以分为两种:
    1.JDK动态代理,在运行时,jvm动态的生成代理类的class字节码数据,然后从字节码数据中创建代理对象的Class实例,拿到Class实例后通过Java反射生成代理类。这个二进制文件可以是本地,也可以是网络的只要能被java验证通过就可以创建成新的对象。
    具体示例如下:
    父类接口:

    package com.example.demo.proxy.jdk;
    
    public interface Person {
    
        void doing();
    }
    
    

    子类:

    package com.example.demo.proxy.jdk;
    
    public class Kevin implements Person {
        @Override
        public void doing() {
            System.out.println("I like basketball.");
        }
    }
    
    

    代理类:

    package com.example.demo.proxy.jdk;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class KevinProxy implements InvocationHandler{
    
        private Object target;
        public KevinProxy(Object target){
            this.target= target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("do before.");
            Object result= method.invoke(target,args);
            System.out.println("do after.");
            return result;
        }
    }
    
    

    测试:

    package com.example.demo.proxy.jdk;
    
    import java.lang.reflect.Proxy;
    
    
    public class Test {
    
        public static void test(){
            Person person= (Person) Proxy.newProxyInstance(Kevin.class.getClassLoader(),Kevin.class.getInterfaces(),new KevinProxy(new Kevin()));
            person.doing();
            System.out.println(person.getClass().getName());
        }
    
        public static void main(String[] args) {
            test();
        }
    }
    
    

    2.CGLIB动态代理是基于java开源字节码生成框架ASM,它可以以二进制的形式修改或者生成新的类,在运行时动态生成一个要代理类的子类,因为是子类所以final方法不能被重写。
    代码如下:
    接口:

    package com.example.demo.proxy.cglib;
    
    public class Lisa {
        public void doing(){
            System.out.println("lisa like coffee");
        }
    }
    
    

    代理类:

    package com.example.demo.proxy.cglib;
    
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    public class LisaProxy implements MethodInterceptor {
        private Enhancer enhancer= new Enhancer();
    
        public Object getProxy(Class clazz){
            enhancer.setSuperclass(clazz);
            enhancer.setCallback(this);
            return enhancer.create();
        }
    
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("doing before");
            Object result= methodProxy.invokeSuper(o,objects);
            System.out.println("doing end");
            return result;
        }
    }
    

    测试:

    package com.example.demo.proxy.cglib;
    
    public class Test {
    
        public static void main(String[] args) {
            Lisa lisa= (Lisa) new LisaProxy().getProxy(Lisa.class);
            lisa.doing();
            System.out.println(lisa.getClass().getName());
        }
    }
    
    

    相关文章

      网友评论

        本文标题:Java动态代理

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