标签:port jar包 color etc div cer bsp invoke 类加载器
基本类图
静态代理
Client.java文件
package com.waibizi.static_proxy; public class Client { public static void main(String[] args) { //创建目标对象,也就是被代理的对象 Dao dao = new Dao(); //创建代理对象,并将被代理的对象传入进去 DaoProxy daoProxy = new DaoProxy(dao); //通过代理对象调用代理对象的方法 //实际上是调用了代理对象之后,由代理对象内部去调用目标对象的方法 daoProxy.operation(); } }
Dao.java文件
package com.waibizi.static_proxy; //目标对象 public class Dao implements IDao{ @Override public void operation() { System.out.println("真正的功能"); } }
DaoProxy.java文件
package com.waibizi.static_proxy; //代理对象 public class DaoProxy implements IDao{ private IDao dao; public DaoProxy(IDao dao) { this.dao=dao; } @Override public void operation() { System.out.println("开始代理!!"); dao.operation(); System.out.println("代理完成"); } }
Idao.java文件
package com.waibizi.static_proxy; //接口 public interface IDao { public void operation(); }
动态代理
Client.java文件
package com.waibizi.dynamic_proxy; import static sun.misc.ProxyGenerator.generateProxyClass; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; //动态代理 public class Client { public static void main(String[] args) { //创建目标对象,也就是被代理的对象 IDao dao = new Dao(); //给目标对象创建代理对象,可以转为Idao IDao daoProxy=(IDao) new ProxyFactory(dao).getProxyInstance(); //System.out.println(dao.toString()); daoProxy.operation(); //比对daoProxy究竟是什么 System.out.println(daoProxy instanceof Proxy); } }
Dao.java文件
package com.waibizi.dynamic_proxy; //目标对象 public class Dao implements IDao{ @Override public void operation() { System.out.println("真正的功能"); } }
IDao.java文件
package com.waibizi.static_proxy; //接口 public interface IDao { public void operation(); }
为了防止代码阅读性太差,这里把代理抽取出来单独调用
ProxyFactory.java文件
package com.waibizi.dynamic_proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * * @author waibizi * *原理:代理类也是一个类,一个类的本质,不就是先从一个.java的后缀文件,转换成.class文件,然后再编译转换为我们的对象二进制流 *那么,追根到底还是一个文件,我们只需要把文件生成出来,后缀名改为.java,里面的内容变成动态的 *分析文件: * 一个java文件有什么 * package内容 * import内容 * ...... *等等,这些无非都是字符串,万物皆对象,传进来一个Object,进行读取里面的内容,动态生成一个专属的类,即可 */ public class ProxyFactory { //维护目标对象 private Object target; public ProxyFactory(Object target) { this.target=target; } //给目标对象生成代理对象 public Object getProxyInstance() { /** * 动态代理: * 作用:在不改变源码的情况下,对已有的方法进行增强 * 特点:字节码随用随创建,随用随加载 * 分类:基于接口的动态代理 * 基于子类的动态代理 * 基于接口的动态代理: * 要求:被代理类至少实现一个接口 * 涉及类:proxy * 提供者:jdk * 创建对象的方法:newProxyInstance * 方法的参数: * 类加载器:ClassLoader,加载代理对象字节码,和被代理对象用一个类加载器 * 字节码数组:Class[] 代理对象和被代理对象要具有相同的行为,实现相同接口 * 如果被代理对象是一个实现类:对象.getClass().getinterfaces() * 如果被代理对象是一个接口:new Class[]{interface} * 增强方法的接口:InvocationHandler,如何增强,如何代理 */ return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { /** * proxy:代理对象 * method:正在调用的方法 * args[]:正在调用的方法的实际参数 */ public Object invoke(Object proxy, Method method,Object[] args) throws Exception{ System.out.println("JDK代理开始!!!"); //试图打印proxy的hashCode的值,发现无法进行打印,程序会尝试重新执行执行多次(toString也不可以) //!System.out.println(proxy.hashCode()); //试图打印method,是可以打印的 //System.out.println(method.toString()); //反射机制调用目标对象的方法 Object value = method.invoke(target,args); System.out.println("代理结束!!!"); return value; } } ); } }
cglib代理,这也是一种动态代理,只不过不是由JDK直接提供的API,需要引入包
cglib相关的jar包:链接:https://pan.baidu.com/s/1xOK_s8cZuza7ruz8ZHZWXw 提取码:d7qe
Client.java文件
package com.waibizi.cglib_proxy; public class Client { public static void main(String[] args) { Dao dao = new Dao(); Dao proxyFactory = (Dao)new ProxyFactory(dao).getProxyInstance(); proxyFactory.operation(); } }
Dao.java文件
package com.waibizi.cglib_proxy; public class Dao { public void operation() { System.out.println("真正的功能"); } }
ProxyFactory.java文件
package com.waibizi.cglib_proxy; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class implements MethodInterceptor{ //维护一个目标对象 private Object target; public ProxyFactory(Object target) { this.target=target; } //返回代理对象,是target对象的代理对象 public Object getProxyInstance() { //1.创建一个工具类 Enhancer enhancer = new Enhancer(); //2.设置父类 enhancer.setSuperclass(target.getClass()); //3.设置回调函数 enhancer.setCallback(this); //4.创建子类 return enhancer.create(); } /** *代理对象的每个方法都会执行当前方法 拦截 * @param proxy 代理类对象引用 * @param method 当前执行的方法 * @param args 执行当前方法需要的参数 * @param methodProxy 执行当前方法的代理类对象 * @return * @throws Throwable */ @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("启动cglib代理"); Object value=method.invoke(target, args); System.out.println("cglib代理完成"); return value; } }
标签:port jar包 color etc div cer bsp invoke 类加载器
原文地址:https://www.cnblogs.com/waibizi/p/12303890.html