动态代理
- 定义:当想要给实现了某个接口的类中的方法,加一些额外的处理。比如说加日志,加事务等。可以给这个类创建一个代理,顾名思义就是创建一个新的类,这个类不仅包含原来类方法的功能,而且还在原来的基础上添加了额外处理的心累。这个代理类并不是定义好的,是动态生成的。具有解耦意义,灵活,拓展性强。
- 动态代理应用:
- spring的aop
- 加事务
- 加日志
- 加权限
- 怎么实现动态代理
-
从静态代理到动态代理
- 举个例子,有些人到了适婚年龄,会被父母催婚。而现在在各种压力之下,很多人都选择晚婚晚育。于是着急的父母就开始到处为子女相亲,比子女自己还着急。下面来看代码实现。创建顶层接口IPerson的代码如下。
public interface IPerson { void findLove(); }
- 儿子张三要找对象,实现ZhangSan类。
public class ZhangSan implements IPerson { public void findLove() { System.out.println("儿子张三提出要求"); } }
- 儿子张三要找对象,实现ZhangSan类。
public class ZhangSan implements IPerson { public void findLove() { System.out.println("儿子张三提出要求"); } }
- 父亲张老三要帮儿子张三相亲,实现ZhangLaosan类。
public class ZhangLaosan implements IPerson { private ZhangSan zhangsan; public ZhangLaosan(ZhangSan zhangsan) { this.zhangsan = zhangsan; } public void findLove() { System.out.println("张老三开始物色"); zhangsan.findLove(); System.out.println("开始交往"); } }
- 来看客户端测试代码。
public class Test { public static void main(String[] args) { ZhangLaosan zhangLaosan = new ZhangLaosan(new ZhangSan()); zhangLaosan.findLove(); } }
- 运行结果如下图所示。
张老三开始物色 儿子张三提出要求 开始交往
弊端:就是自己的父亲只会帮自己的子女去物色对象,别人家的孩子是不会管的。但社会上这项业务发展成了一个产业,出现了媒婆、婚介所等,还有各种各样的定制套餐。如果还使用静态代理成本就太高了,需要一个更加通用的解决方案,满足任何单身人士找对象的需求。这就由静态代理升级到了动态代理。采用动态代理基本上只要是人(IPerson)就可以提供相亲服务。动态代理的底层实现一般不用我们亲自去实现,已经有很多现成的API。在Java生态中,目前普遍使用的是JDK自带的代理和CGLib提供的类库。首先基于JDK的动态代理支持来升级一下代码。
- 首先创建媒婆(婚介所)类JdkMeipo。
public class JdkMeipo implements InvocationHandler { private IPerson target; public IPerson getInstance(IPerson target){ this.target = target; Class<?> clazz = target.getClass(); return (IPerson) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(),this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); Object result = method.invoke(this.target,args); after(); return result; } private void after() { System.out.println("双方同意,开始交往"); } private void before() { System.out.println("我是媒婆,已经收集到你的需求,开始物色"); } }
- 然后创建一个类ZhaoLiu。
public class ZhaoLiu implements IPerson { public void findLove() { System.out.println("符合赵六的要求"); } public void buyInsure() { } }
- 然后创建一个类ZhaoLiu。
public static void main(String[] args) { JdkMeipo jdkMeipo = new JdkMeipo(); IPerson zhaoliu = jdkMeipo.getInstance(new ZhaoLiu()); zhaoliu.findLove(); }
- 运行结果如下所示。
我是媒婆,已经收集到你的需求,开始物色 符合赵六的要求 双方同意,开始交往