动态代理:jdk动态代理和cglib动态代理

/**
 * 动态代理类:先参考代理模式随笔,了解代理模式的概念,分为jdk动态代理和cglib,jdk动态代理是通过实现接口的方式创建代理类的,cglib是通过继承类的方式实现的代理类的
 * jdk动态代理需要用到jdk自带的一个类Proxy来生成代理类,还需要一个提供执行方法的执行接口InvocationHandler.代理类是底层反编译后是可以看到是调用
 * InvocationHandler的invoke方法实现
 *
 *
 */
//父接口
public interface IRun {
    void run();
}
//被代理类
public class Runner implements IRun {
    @Override
    public void run() {
        System.out.println("运动员开跑...............");
    }
}
//实现一个执行类,代理类底层是通过这个类来执行被代理类的方法

public class MyInvocationHandler implements InvocationHandler {
    private IRun run; //被代理类

    public MyInvocationHandler(IRun run) {
        this.run = run;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("执行之前进行检查");
        method.invoke(run,args); //反射执行被代理类的方法
        System.out.println("执行之后.....");
        return null;
    }

    //通过Proxy获取获取代理类
    public IRun getProxy(){

        return (IRun) Proxy.newProxyInstance(run.getClass().getClassLoader(),run.getClass().getInterfaces(),this);
    }


    //Proxy.newProxyInstance()底层是调用ProxyGenerator.generateProxyClass来生成字节码的,这里模拟实现,将代理生成的字节码文件输出来,然后反编译
    public static void createProxyClassFile(){//生成字节码对象
        String name = "ProxyRun.class";
        byte[] data = ProxyGenerator.generateProxyClass(name,new Class[]{IRun.class});
        FileOutputStream out =null;
        try {
            out = new FileOutputStream( System.getProperty("user.dir") + File.separator + name);
            out.write(data);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(null!=out) try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
public class Test {
    public static void main(String[] args) {
        Runner runner = new Runner();//被代理类
        MyInvocationHandler handler = new MyInvocationHandler(runner);//执行处理的类
        IRun proxy = handler.getProxy();//获取代理类
        proxy.run();//代理类执行方法
        //输出代理类的字节码文件,通过反射可以看到实现原理
        MyInvocationHandler.createProxyClassFile();
    }

}
//对代理类字节码文件反编译,可以看到是通过实现IRun接口
public final class $proxy0 class extends Proxy implements IRun {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m0;

    public class(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue();
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void run() throws  {
        try {
            //可见底层是调用InvocationHandler的invoke方法
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue();
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
            m3 = Class.forName("builder.IRun").getMethod("run", new Class[0]); //run方法
            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}
//cglib实现动态代理,该方式因为不是jdk自带的,所以需要引入相应的依赖包(spring框架自带相应的依赖包了),代理类需要实现MethodInterceptor相当于jdk动态代理的InvocationHandler,
//覆写intercept相当于InvocationHandler的invoke方法,生成代理类是通过Enhancer类来生成的
public class Dog {

    public void sout(){
        System.out.println("汪汪");
    }
}
public class DogProxy implements MethodInterceptor {


    private Dog target;
    public DogProxy(Dog target) {
        this.target = target;
    }
    public Object bind(){
        Enhancer enhancer = new Enhancer();//创建加强器,用来创建动态代理类
        enhancer.setSuperclass(target.getClass());//为加强器指定要代理的业务类(即:为下面生成的代理类指定父类)
        enhancer.setCallback(this); //设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("开始");
        method.invokeSuper(o,objects);
        System.out.println("结束");
        return null;
    }
}

猜你喜欢

转载自www.cnblogs.com/yangxiaohui227/p/10913593.html