无意间想到java动态代理,百度一搜,简直多得吓人,但是自己没有看到一篇写的通俗易懂的,也有很多简析了深层原理的,所以自己也写一篇,写得不好,望见谅:
学习代理,先从概念入手:为其他对象提供一种代理来控制对这个对象的访问,所以代理起到的是中介的作用,可以去掉功能服务,也可以增加额外额功能服务
代理的分类有很多:比如远程代理,虚拟代理,保护代理,智能引用代理
从实现方式共分为两大类:动态代理和静态代理;
静态代理:有一个很有意思的叫法,装饰模式,即向原有的对象包装一下,现实中这样的例子很多,比如房子的装修,同样的一座大楼,每一层的架构都一样,但是不同的住户,
喜欢不同的风格,所以就装修成不一样,实现方式就继承模式和聚合模式,这两种方式的实现方式太简单,园子这样的文章太多了
动态代理:目前我知道的实现方式就基于JDK的,cglib的实现方式
本文就基于JDK动态代理实现方式做简单介绍:
1.创建一个事务处理器,TimeAndLogProxy并实现InvocationHandler
package com.mitko.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * 动态代理的实现方式 * 该类实现时间和日志功能的打印 * 代理类必须实现InvocationHandler中invoke方法,业务逻辑都在此方法中实现 * @author Administrator * */ public class TimeAndLogProxy implements InvocationHandler { //代理对象 private Object target; public TimeAndLogProxy(Object target) { this.target = target; } /** * proxy 代理对象 * method 代理对象的方法 * args 方法参数 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Long beginTime = System.currentTimeMillis(); System.out.println("日志记录开始:"); Thread.sleep(10); method.invoke(target); Long endTime = System.currentTimeMillis(); System.out.println("运行时间:"+(endTime-beginTime)+"ms "+"日志记录结束...."); return null; } }
2.创建一个接口
** * 所有实体类的共有的方法 * @author Administrator * */ public interface MoveAble { public abstract void move(); }
3.创建被代理类并实现上面创建的接口
package com.mitko.model; import com.mitko.MoveAble; /** * 独立类 * @author Administrator * */ public class Car implements MoveAble { @Override public void move() { System.out.println("汽车行驶在路上。。。。"); } }
至此,JDK动态代理实现就完成了,下面是测试
/** * 测试类 * @author Administrator * */ public class ProxyTest { @Test public void test(){ //代理的真实类,两种写法都可以 Car car = new Car(); MoveAble real = new Car(); //创建事务处理器并传入需要代理的类 TimeAndLogProxy talp = new TimeAndLogProxy(real); //通过Proxy创建被代理对象 //loader 事务处理器的类加载器 //interface 被代理对象所实现的接口 //invocationHandler 事务处理器 MoveAble m = (MoveAble)Proxy.newProxyInstance( talp.getClass().getClassLoader(), real.getClass().getInterfaces(), talp); m.move(); } }
测试结果
以上就是jdk动态代理的实现过程,但是有一个局限性,jdk动态代理只能代理有实现接口的类,不能代理没有实现接口的类,这点与cglib有区别
欢迎大家在下面留言评论指正