/** * 动态代理类:先参考代理模式随笔,了解代理模式的概念,分为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; } }
动态代理:jdk动态代理和cglib动态代理
猜你喜欢
转载自www.cnblogs.com/yangxiaohui227/p/10913593.html
今日推荐
周排行