首先要明确一点:代理的对象是一件事情!如何理解这句话?举个栗子:我是某一个地区白酒经营的总代理。说白了就是我是一个卖酒的,我代理的是一件事,那就是帮别人卖酒。我从白酒生产厂家那里获得白酒,并把它卖出去,我从中赚取差价。(在生活中只要不是生产商去直接销售,中间商都简称代理,实际上代理指的是某一件具体的事)

上面说了比较多的废话主要想说明代理是什么?那么代理的关系又是什么呢?其实代理就可以简单理解为是中间商。它不需要亲自去生产制造,只要专心做某一件事就好了。还是白酒,不需要去酿酒,只需要把酒卖出去就好了。而对于卖白酒这件事来说并没有太多约束,假如我是一个地区的白酒总代理,那么卖什么总类的酒对我来说并不用太过在意,因为我只是去卖白酒,不管是卖茅台、五粮液还是二锅头或牛栏山对我本人来说倒是无所谓。

代理有什么用呢?

还是拿白酒来举例:比如一个消费者想买一瓶二锅头和一瓶五粮液。如果没有代理那么这个消费者就需要去找五粮液的生产厂家,然后从生产厂家那里获得一瓶五粮液。然后再去找二锅头生产厂家,然后从那里买一瓶二锅头。这样一来是非常非常不方便的。那么有了代理之后,这位消费者直接去到代理那里说要买一瓶五粮液和一瓶二锅头。代理直接就从这个厂家那里拿货就好了,只不过需要赚取一点辛苦费。但是对于消费者来说不需要那么麻烦了买这两种酒就很方便。

引申到Java中来说,传统的创建方法都是直接new一个对象出来。如果有两个对象那么代码就需要写两次,要new两遍,代码非常不灵活。

五粮液酒厂类:

二锅头酒厂类:

传统方式:

以上面的买白酒为例:

一个消费者需要买一瓶五粮液和一瓶二锅头,那么首先要有一个五粮液酒厂家的类和一个二锅头厂家的类。这两个类中分别都有一个卖白酒的方法sellWine(),在买酒的时候分别将两个酒厂家对象都new出来,然后再调用里面的sellWine()方法。反正都是要去买酒,那么我们可以想象一下,如果有人能够代替你去完成创建对象的操作就好了。也就是说反正我是要买酒,如果我需要买一瓶五粮液那么就有人能给我new一个五粮液酒厂家对象,如果我需要一瓶二锅头那么再给我new一个二锅头厂家对象那就方便很多了。我只要提供白酒厂家的名字(这个厂家必须要先存在),他就能自己去动态的给我创建一个白酒厂家的对象。那么这就是动态代理。需要什么对象这种机制就能动态创建什么对象,同时能调用对象当中的方法执行。还可以将原来的功能再进行扩展。还以买白酒为例,消费者去买一瓶五粮液白酒,代理就创建一个五粮液酒厂对象还能调用这个酒厂类中的卖酒方法sellWine(),从而获得白酒的原厂价格。当拿到原厂价格之后,代理还能对此价格进行额外的处理,比如每瓶酒加价10%之后再卖出去。这就调用了酒厂类中的方法并进行额外的扩展。

那么上面说了这么多JDK动态代理的代码应该怎么写呢?

jdk 动态代理是代理模式的一种实现方式,其只能代理接口。
实现步骤
1、新建一个接口,作为目标接口
2、为接口创建一个实现类,是目标类
3、创建类实现 java.lang.reflect.InvocationHandler 接口,调用目标方法并增加其他功能代码
4、创建动态代理对象,使用 Proxy.newProxyInstance()方法,并把返回值强制转为接口类型。
上面四步按照卖白酒的例子来说就是:
1、定义一个接口,这个接口内规定就是代理是一件什么事
public interface SellWine {int sell(int amount);
}

2、定义白酒生产厂商,并要实现卖白酒的接口

定义一个茅台厂家

public class MaoTaiSellWineImpl implements SellWine {@Overridepublic int sell(int amount) {int price = amount * 1250;return price;}
}

定义一个五粮液厂家

public class WuLiangYeSellWineImpl implements SellWine {@Overridepublic int sell(int amount) {int fee = amount * 1000;return fee;}
}

定义一个二锅头厂家

public class ErGuoTouSellWineImpl implements SellWine {@Overridepublic int sell(int amount) {int fee = amount * 50;return fee;}
}

3、这一步就好比是一个代理要代理卖白酒这件事,要事先拟定好合同签订协议的过程(每一瓶白酒加价多少等等这些扩招功能)

public class MySellWineInvocationHandler implements InvocationHandler {/** 要代理卖白酒这件事,明确要卖谁生产的白酒,代理对象就是白酒生产厂家* *///让目标对象有代理功能private Object target;public MySellWineInvocationHandler() {}public MySellWineInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//确定关系,从厂商那里拿酒卖(这里用到的是反射机制)Object feeObj = method.invoke(target,args);int feeAmount = (int) feeObj;//扩展功能,代理卖白酒需要加价获利(每次获利为厂家拿货价的0.05)int totalFee = feeAmount + (feeAmount / 20);return totalFee;}
}

4、拟定好协议之后才真正开始创建一个动态代理对象,开始代理卖白酒这件事

public class WineAgentObjectTest {public static void main(String[] args) {Object wineSell = null;try {Class wines = Class.forName("com.feiHuTechnologyCompany.jdkDynamicProxy.wine.impl.ErGuoTouSellWineImpl");
//      Class wines = Class.forName("com.feiHuTechnologyCompany.jdkDynamicProxy.wine.impl.WuLiangYeSellWineImpl");
//      Class wines = Class.forName("com.feiHuTechnologyCompany.jdkDynamicProxy.wine.impl.ErGuoTouSellWineImpl");//创建白酒生产厂商对象wineSell = wines.newInstance();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();}String wineName;if(wineSell.getClass().getSimpleName().equals("MaoTaiSellWineImpl")){wineName = "茅台";}else if(wineSell.getClass().getSimpleName().equals("WuLiangYeSellWineImpl")){wineName = "五粮液";}else{wineName = "其他种类";}//创建调用处理器(展示代理合同,合同内容大致为谁代理了什么事,扩展了什么功能)InvocationHandler handler = new MySellWineInvocationHandler(wineSell);//创建动态代理对象SellWine wo = (SellWine) Proxy.newProxyInstance(wineSell.getClass().getClassLoader(),wineSell.getClass().getInterfaces(),handler);//代理卖白酒int amount = 10;int price = wo.sell(amount);System.out.println("从我这买"+amount+"瓶"+wineName+"酒需要"+price+"大洋");}
}

传入不同的白酒生产厂商后得到的结果分别如下(顺序是茅台、五粮液、二锅头)

可以看到传入的类可以写入配置文件当中,当修改配置文件后就能动态的创建对象并调用方法执行,还可以进行功能的扩展,不需要自己再去new对象。java许多框架都用到了jdk动态代理和反射机制来实现对象的创建。

(一个尚未工作,在code路上疯狂踩坑并努力爬起的小学生。上述表述如有误,请批评指正!谢谢!)

JDK动态代理(通俗白话)相关推荐

  1. cglib动态代理和jdk动态代理的区别与应用

    1,引入 如果从一个Controller调用Service的非事务方法a,然后在a里调用事务方法b,b事务生效吗? public void update() {updateActual();int a ...

  2. (转)面试必备技能:JDK动态代理给Spring事务埋下的坑!

    一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...

  3. 【spring】初识aop(面向切面编程) 使用jdk动态代理

    BankServiceIImple.java 代码实现: package com.zzxtit.aop;import java.math.BigDecimal;public interface Ban ...

  4. 【原创】分布式之缓存击穿 【原创】自己动手实现静态资源服务器 【原创】自己动手实现JDK动态代理...

    [原创]分布式之缓存击穿 什么是缓存击穿 在谈论缓存击穿之前,我们先来回忆下从缓存中加载数据的逻辑,如下图所示 因此,如果黑客每次故意查询一个在缓存内必然不存在的数据,导致每次请求都要去存储层去查询, ...

  5. 【干货】JDK动态代理的实现原理以及如何手写一个JDK动态代理

    动态代理 代理模式是设计模式中非常重要的一种类型,而设计模式又是编程中非常重要的知识点,特别是在业务系统的重构中,更是有举足轻重的地位.代理模式从类型上来说,可以分为静态代理和动态代理两种类型. 在解 ...

  6. aop的四种增强以及JDK动态代理、Cglib动态代理

    动态代理 AOP底层实现:有接口自动应用的就是JDK动态代理 (1).JDK 在运行时运行时注入 本质:在内存中构建出接口的实现类 特点:被代理对象,必须有接口 实例: import java.lan ...

  7. JDK动态代理小例子

    一个小汽车,有一个跑run()的方法,我们想使用jdk动态代理使小汽车执行run之前 加点油,run之后洗车. 有四个类,接口Car(小汽车)Kayan(具体实现类(卡宴)) CarProxy(汽车的 ...

  8. jdk动态代理实例和cglib动态代理实例_CGLib 动态代理 原理解析

    JDK 动态代理实现与原理 首先来看一段CGLib代理的测试代码(MethodInterceptor的测试, 其他类型这里不做展开了). Util类的代码在后面给出的码云片段中 public 下面的输 ...

  9. java jdk动态代理学习记录

    转载自: https://www.jianshu.com/p/3616c70cb37b JDK自带的动态代理主要是指,实现了InvocationHandler接口的类,会继承一个invoke方法,通过 ...

  10. 利用JDK动态代理机制实现简单拦截器

    利用JDK动态代理机制实现简单的多层拦截器 首先JDK动态代理是基于接口实现的,所以我们先定义一个接口 public interface Executer {public Object execute ...

最新文章

  1. jquery checkbox勾选/取消勾选的诡异问题
  2. Error(s) in loading state_dict
  3. python UnicodeEncodeError 编码错误总结
  4. 解决 “OperationalError: (sqlite3.OperationalError) no such table: ...“问题
  5. 在Redhat 5.0 上安装Eclipse 3.6
  6. arm linux 内核启动,Linux(ARM)内核启动地址
  7. 文巾解题 283. 移动零
  8. ML之DT:机器学习根据大量数据,已知年龄、收入、是否上海人、私家车价格的一个人,预测是否有真实购买上海黄浦区楼房的能力
  9. 三种方式在CentOS 7搭建KVM虚拟化平台
  10. java程序猿面试问缺点怎么回答_JAVA程序员面试32问,你能回答多少题
  11. uniapp image图片切换动效_动效设计从概念到落地
  12. LSMW--一个中文介绍的摘抄
  13. 电子邮件地址验证:详细解释,生产质量WPF文本框代码
  14. Python 字符串(三)-字符串操作实例(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
  15. [Linux系统] VMware克隆CentOS7,解决网络配置问题
  16. python获取文件名中两条下划线之间的部分_Python 中的特殊双下划线方法
  17. 软考 数据库系统工程师
  18. 手工打造迅雷9超精简版
  19. micropython移植增加驱动,MicroPython之LPC1788移植
  20. android转场动画的两种方式

热门文章

  1. 计算机继电保护书籍,计算机继电保护的发展
  2. Quartus II 13.1的安装及使用
  3. lua 常用数据类型总结
  4. java正则表达式大全(常用)
  5. CI框架redirect自动加上了index.php问题
  6. hibernate还有人用吗
  7. 对抗型交叉评价DEA模型matlab代码
  8. android gradle下载
  9. 阿里巴巴Java开发手册 PDF
  10. 声音鉴定-趣味测试-源码