JDK动态代理(通俗白话)
首先要明确一点:代理的对象是一件事情!如何理解这句话?举个栗子:我是某一个地区白酒经营的总代理。说白了就是我是一个卖酒的,我代理的是一件事,那就是帮别人卖酒。我从白酒生产厂家那里获得白酒,并把它卖出去,我从中赚取差价。(在生活中只要不是生产商去直接销售,中间商都简称代理,实际上代理指的是某一件具体的事)
上面说了比较多的废话主要想说明代理是什么?那么代理的关系又是什么呢?其实代理就可以简单理解为是中间商。它不需要亲自去生产制造,只要专心做某一件事就好了。还是白酒,不需要去酿酒,只需要把酒卖出去就好了。而对于卖白酒这件事来说并没有太多约束,假如我是一个地区的白酒总代理,那么卖什么总类的酒对我来说并不用太过在意,因为我只是去卖白酒,不管是卖茅台、五粮液还是二锅头或牛栏山对我本人来说倒是无所谓。
代理有什么用呢?
还是拿白酒来举例:比如一个消费者想买一瓶二锅头和一瓶五粮液。如果没有代理那么这个消费者就需要去找五粮液的生产厂家,然后从生产厂家那里获得一瓶五粮液。然后再去找二锅头生产厂家,然后从那里买一瓶二锅头。这样一来是非常非常不方便的。那么有了代理之后,这位消费者直接去到代理那里说要买一瓶五粮液和一瓶二锅头。代理直接就从这个厂家那里拿货就好了,只不过需要赚取一点辛苦费。但是对于消费者来说不需要那么麻烦了买这两种酒就很方便。
引申到Java中来说,传统的创建方法都是直接new一个对象出来。如果有两个对象那么代码就需要写两次,要new两遍,代码非常不灵活。
五粮液酒厂类:
二锅头酒厂类:
传统方式:
以上面的买白酒为例:
一个消费者需要买一瓶五粮液和一瓶二锅头,那么首先要有一个五粮液酒厂家的类和一个二锅头厂家的类。这两个类中分别都有一个卖白酒的方法sellWine(),在买酒的时候分别将两个酒厂家对象都new出来,然后再调用里面的sellWine()方法。反正都是要去买酒,那么我们可以想象一下,如果有人能够代替你去完成创建对象的操作就好了。也就是说反正我是要买酒,如果我需要买一瓶五粮液那么就有人能给我new一个五粮液酒厂家对象,如果我需要一瓶二锅头那么再给我new一个二锅头厂家对象那就方便很多了。我只要提供白酒厂家的名字(这个厂家必须要先存在),他就能自己去动态的给我创建一个白酒厂家的对象。那么这就是动态代理。需要什么对象这种机制就能动态创建什么对象,同时能调用对象当中的方法执行。还可以将原来的功能再进行扩展。还以买白酒为例,消费者去买一瓶五粮液白酒,代理就创建一个五粮液酒厂对象还能调用这个酒厂类中的卖酒方法sellWine(),从而获得白酒的原厂价格。当拿到原厂价格之后,代理还能对此价格进行额外的处理,比如每瓶酒加价10%之后再卖出去。这就调用了酒厂类中的方法并进行额外的扩展。
那么上面说了这么多JDK动态代理的代码应该怎么写呢?
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动态代理(通俗白话)相关推荐
- cglib动态代理和jdk动态代理的区别与应用
1,引入 如果从一个Controller调用Service的非事务方法a,然后在a里调用事务方法b,b事务生效吗? public void update() {updateActual();int a ...
- (转)面试必备技能:JDK动态代理给Spring事务埋下的坑!
一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...
- 【spring】初识aop(面向切面编程) 使用jdk动态代理
BankServiceIImple.java 代码实现: package com.zzxtit.aop;import java.math.BigDecimal;public interface Ban ...
- 【原创】分布式之缓存击穿 【原创】自己动手实现静态资源服务器 【原创】自己动手实现JDK动态代理...
[原创]分布式之缓存击穿 什么是缓存击穿 在谈论缓存击穿之前,我们先来回忆下从缓存中加载数据的逻辑,如下图所示 因此,如果黑客每次故意查询一个在缓存内必然不存在的数据,导致每次请求都要去存储层去查询, ...
- 【干货】JDK动态代理的实现原理以及如何手写一个JDK动态代理
动态代理 代理模式是设计模式中非常重要的一种类型,而设计模式又是编程中非常重要的知识点,特别是在业务系统的重构中,更是有举足轻重的地位.代理模式从类型上来说,可以分为静态代理和动态代理两种类型. 在解 ...
- aop的四种增强以及JDK动态代理、Cglib动态代理
动态代理 AOP底层实现:有接口自动应用的就是JDK动态代理 (1).JDK 在运行时运行时注入 本质:在内存中构建出接口的实现类 特点:被代理对象,必须有接口 实例: import java.lan ...
- JDK动态代理小例子
一个小汽车,有一个跑run()的方法,我们想使用jdk动态代理使小汽车执行run之前 加点油,run之后洗车. 有四个类,接口Car(小汽车)Kayan(具体实现类(卡宴)) CarProxy(汽车的 ...
- jdk动态代理实例和cglib动态代理实例_CGLib 动态代理 原理解析
JDK 动态代理实现与原理 首先来看一段CGLib代理的测试代码(MethodInterceptor的测试, 其他类型这里不做展开了). Util类的代码在后面给出的码云片段中 public 下面的输 ...
- java jdk动态代理学习记录
转载自: https://www.jianshu.com/p/3616c70cb37b JDK自带的动态代理主要是指,实现了InvocationHandler接口的类,会继承一个invoke方法,通过 ...
- 利用JDK动态代理机制实现简单拦截器
利用JDK动态代理机制实现简单的多层拦截器 首先JDK动态代理是基于接口实现的,所以我们先定义一个接口 public interface Executer {public Object execute ...
最新文章
- jquery checkbox勾选/取消勾选的诡异问题
- Error(s) in loading state_dict
- python UnicodeEncodeError 编码错误总结
- 解决 “OperationalError: (sqlite3.OperationalError) no such table: ...“问题
- 在Redhat 5.0 上安装Eclipse 3.6
- arm linux 内核启动,Linux(ARM)内核启动地址
- 文巾解题 283. 移动零
- ML之DT:机器学习根据大量数据,已知年龄、收入、是否上海人、私家车价格的一个人,预测是否有真实购买上海黄浦区楼房的能力
- 三种方式在CentOS 7搭建KVM虚拟化平台
- java程序猿面试问缺点怎么回答_JAVA程序员面试32问,你能回答多少题
- uniapp image图片切换动效_动效设计从概念到落地
- LSMW--一个中文介绍的摘抄
- 电子邮件地址验证:详细解释,生产质量WPF文本框代码
- Python 字符串(三)-字符串操作实例(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
- [Linux系统] VMware克隆CentOS7,解决网络配置问题
- python获取文件名中两条下划线之间的部分_Python 中的特殊双下划线方法
- 软考 数据库系统工程师
- 手工打造迅雷9超精简版
- micropython移植增加驱动,MicroPython之LPC1788移植
- android转场动画的两种方式