我爱编程

Java动态代理

2018-05-22  本文已影响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());
    }
}

上一篇下一篇

猜你喜欢

热点阅读