什么叫代理
代理模式是常用的 java 设计模式. 代理类主要负责为委托类 (被代理对象) 预处理消息, 过滤消息, 把消息转发给委托类, 以及事后处理消息等.
代理类与委托类之间通常会存在关联关系, 一个代理类的对象与一个委托类的对象关联, 代理类的对象本身并不真正实现服务, 而是通过调用委托类的对象的相关方法, 来提供特定的服务.
代理类在执行被代理类的功能方法前后, 加入一些业务逻辑: 权限的验证, 事务的处理, 日志的记录.
动态代理的实现方法
动态代理的代理类是动态生成的, 代理类的字节码将在运行时生成, 并载入当前的 ClassLoader, 如果被代理类实现了接口, 可以使用 jdk 提供的 Proxy,InvocationHandler 实现.
友情提示
热心小编: ylz2117949797
小余老师刚学习 jdk 的动态代理的时候, 一脸懵逼, 这是啥玩意儿啊? 为了让大家对 jdk 的动态代理学起来通俗易懂, 小余老师给大家讲一个自己刚毕业找工作时, 去中介公司租房子亲身经历的故事.
第一步, 咱们先创建一个出租房子的接口 Rent.
- public interface Rent {
- // 出租房子
- public void rent();
- }
第二步, 小余老师问你们, 是谁要出租房子啊? 嗯, 当然是房东了, 所以咱们要假想一个人, 建个类是房东 Host , 他要出租房子, 实现 Rent 这个接口.
- public class Host implements Rent{
- @Override
- public void rent() {
- System.out.println('我是房东, 我要出租房子');
- }
- }
第三步, 咳咳, 重点了啊, 小余老师要去中介公司了, 想要租个房子, 去哪个中介公司呢? 咱造一个, 随便取个名 proInv, 但是这个类必须要实现 InvocationHandler, 这个是调用处理器接口, 自定义 invoke 方法, 用于实现对于真正委托类的代理访问. 看下面代码, 中介公司里面有个方法, 里面有三个参数, 小余老师解释下啊, 第一个参数 proxy 是代理对象, 就是中介公司里面的小中介, 小业务员, 第二个参数是当前调用那个方法, 第三个参数是方法的输入参数. 有人问我了, 里面怎么还有 Host host? 那小余老师问一句, 房东不要去中介公司把房子委托给中介公司嘛!
- public class proInv implements InvocationHandler {
- Host host; // 房东对象
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- return null;
- }
- }
第四步, 小余老师去了名叫 proInv 这个中介公司, 牛逼哄哄地说了一句我要租房子, 然后中介公司给我安排了一 位中介. 看下面代码, Proxy.newProxyInstance, 这个意思就是说给你动态生成了一个新的代理对象. this.getClass().getClassLoader(), 这个是定义代理类的类加载器的意思, 你可以理解为这个中介属于中介公司 proInv,host.getClass().getInterfaces(), 这个是代理类要实现的接口列表的意思, 就是要把房子租出去, 实现出租房子的接口啊. this , 就是指派方法调用的调用处理程序.
- // 生成代理对象(中介)
- public Object getProxy(){
- return Proxy.newProxyInstance(
- this.getClass().getClassLoader(),
- host.getClass().getInterfaces(),
- this
- );
- }
第五步, 公司给我安排了一位中介后, 然后就带我看房子, 使出了浑身解数, 把房子夸上了天, 我觉得还不错, 就付了钱. 看下面代码.
- // 看房子
- public void see(){
- System.out.println('我是中介, 带小余老师看房子');
- }
- // 收取中介费
- public void money(){
- System.out.println('我是中介, 收小余老师中介费');
- }
第六步, 房东出租掉房子之前, 一般的步骤都是中介先带小余老师看房子, 小余老师满意后, 接着收取小余老师的租金, 但是这个钱是不属于他的, 这个行为是属于公司的, 所以要在公司 proInv 里写这个步骤, 也就是在公司里的那个 invoke 方法里面完成这个步骤, 看代码.
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- public class proInv implements InvocationHandler {
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- see(); // 看房子
- Object result = method.invoke(host, args); // 中介真实调用房东的出租房子的能力
- money();// 收取中介费
- return result;
- }
- // 生成代理对象(中介)
- public Object getProxy(){
- return Proxy.newProxyInstance(
- this.getClass().getClassLoader(),// 定义代理类的类加载器
- host.getClass().getInterfaces(), // 代理类要实现的接口列表
- this // 指派方法调用的调用处理程序
- );
- }
- // 看房子
- public void see(){
- System.out.println('我是中介, 带小余老师看房子');
- }
- // 收取中介费
- public void money(){
- System.out.println('我是中介, 收小余老师中介费');
- }
- }
第七步, 到了这, 咱也差不多了, 咱们来测试一下, 看代码.
- public class Test1 {
- public static void main(String[] args) {
- proInv p = new proInv(); // 中介公司
- Host h = new Host(); // 房东
- p.host=h; // 中介公司 与房东建立关联
- Rent pro = (Rent) p.getProxy(); // 中介
- pro.rent();
- }
- }
输出的结果为:
我是中介, 带小余老师看房子
我是房东, 我要出租房子
我是中介, 收小余老师中介费
来源: http://www.92to.com/bangong/2018/04-12/33557205.html