java 代理模式具体解释
java 动态代理(JDK和cglib)
设计模式这东东每次看到就明确可过段时间又不能非常流利的说出来。今天就用具体的比喻和实例来加深自己的理解(小弟水平不高有不正确的地方希望大家能指出来)。
(1)代理这个词生活中有非常多比方在街边卖手机卡、充公交地铁卡的小商店他们都起了代理的作用,java中的代理跟这些小店商的作用是一样的。
再比方我想在淘宝上开个服装店但又没有货源怎么办,这时候我就要跟淘宝上某一卖家联系做他的代理。我跟我的商家都要卖衣服(就好比我们都继承了卖衣服的接口sellClothesInterface),我的商家能够卖他网店上的衣服跟我没的关系(就好比实现了sellClothesInterface接口),我的网店也能够卖代理的衣服(同都也实现了sellClothesInterface接口),这个时候买家从我的网店上买了一件衣服而衣服的发货地址确是我的商家的,买家跟我的商家没有不论什么关系,我就起了代理的作用。
(2)用官方的话:代理模式是经常使用的java设计模式,他的特征是代理类与托付类有相同的接口,代理类主要负责为托付类预处理消息、过滤消息、把消息转发给托付类,以及事后处理消息等。代理类与托付类之间一般会存在关联关系,一个代理类的对象与一个托付类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用托付类的对象的相关方法,来提供特定的服务。
(3)代理分为两种:静态代理和动态代理。
1、静态代理用代码实现例如以下:
public interface SellClothesInterface {
// 都能卖衣服的接口
public void sell();
}
public class BossSellClothes implements SellClothesInterface {
// 我的商家有卖衣服的方法
public void sell() {
System.out.println("确定信息并发货...");
}
}
public class MySellClothes implements SellClothesInterface {
private BossSellClothes bossSellClothes;
// 构造方法
public MySellClothes(BossSellClothes bossSellClothes) {
this.bossSellClothes = bossSellClothes;
}
public void sell() {
// 卖衣服之前先与买家做沟通确定下单
System.out.println("确认信息。确定下单...");
bossSellClothes.sell();
// 买家收货并打款
System.out.println("买家收到货交易结束...");
}
}
@org.junit.Test
public void run1() {
BossSellClothes bossSellClothes = new BossSellClothes();// 我的商家实例类
SellClothesInterface scif = new MySellClothes(bossSellClothes);// 我卖衣服类
scif.sell();// 卖衣服
}
执行结果:
确认信息,确定下单...
确定信息并发货...
买家收到货交易结束...
从上面代码能够发现每个代理类仅仅能为一个接口服务。所有的代理操作除了调用的方法不一样之外,其它的操作都一样,则此时肯定是反复代码。解决这一问题最好的做法是能够通过一个代理类完毕所有的代理功能,那么此时就必须使用动态代理完毕。
2、动态代理
JDK动态代理中包括一个类和一个接口:
InvocationHandler接口:
public interface InvocationHandler {
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
參数说明:
Object proxy:指被代理的对象。
Method method:要调用的方法
Object[] args:方法调用时所须要的參数
能够将InvocationHandler接口的子类想象成一个代理的终于操作类,也就是上面静态代理类MySellClothes。
Proxy类:
Proxy类是专门完毕代理的操作类,能够通过此类为一个或多个接口动态地生成实现类,此类提供了例如以下的操作方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
參数说明:
ClassLoader loader:类载入器,用于找到被代理类。
Class<?>[] interfaces:得到所有的接口 。被代理类实现的所有接口。
InvocationHandler h:得到InvocationHandler接口的子类实。
代码修改发下:
/**
* JDK动态代理
*
* @author Administrator
*
*/
public class SellClothesProxy implements InvocationHandler {
private Object target; /**
* 传入被代理类生成代理类
*
* @param target
* @return
*/
public Object buildProxy(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
} /**
* 调用方法
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("确认信息,确定下单...");
Object result = method.invoke(target, args);
System.out.println("买家收到货交易结束...");
return result;
}
}
@org.junit.Test
public void run2() {
// 创建代理类并调用方法
SellClothesProxy proxy = new SellClothesProxy();
SellClothesInterface scif = (SellClothesInterface) proxy.buildProxy(new BossSellClothes());
scif.sell();
}
执行结果:
确认信息,确定下单...
确定信息并发货...
买家收到货交易结束...
结果出来了,但有一个问题继承InvocationHandler 覆盖invoke方法。那这种方法什么时候被调用的呢?,打个断点发现scif.sell();执行时才调用invoke方法。这个invoke 方法返回一个 Object的实例,然会会强转成你须要的接口。这时候调用你这个接口的方法的时候, 实质上 就是执行了 这个invoke的方法。
(4)cglib动态代理
有了JDK的动态代理再说说cglib。为什么要用cglib呢。JDK的动态代理依靠接口实现,假设有些类并没有实现接口。则不能使用JDK代理,cglib就弥补了这点。cglib是对指定的目标类生成一个子类,并覆盖当中方法实现增强。但既然是类的继承就不能对final修饰的类进行代理了。
public class SellClothesProxy2 implements MethodInterceptor {
private Object target;
/**
* 传入被代理类生成代理类
*
* @param target
* @return
*/
public Object buildProxy(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
// 回调方法
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("确认信息。确定下单...");
proxy.invokeSuper(obj, args);
System.out.println("买家收到货交易结束...");
return null;
}
}
@org.junit.Test
public void run3() {
SellClothesProxy2 proxy = new SellClothesProxy2();
SellClothesInterface scif = (SellClothesInterface) proxy.buildProxy(new BossSellClothes());
scif.sell();
}
执行结果:
确认信息,确定下单...
确定信息并发货...
买家收到货交易结束...
java 代理模式具体解释的更多相关文章
- Java代理模式
java代理模式及动态代理类 1. 代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目 ...
- 设计模式 - 代理模式(proxy pattern) 未使用代理模式 具体解释
代理模式(proxy pattern) 未使用代理模式 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 部分代码參考: http://blog.csdn. ...
- Java代理模式示例程序
Java代理模式示例程序 当然不是我想出来的,是我看的一个网上教程里的. 模拟的是一个对电脑公司的代理 真实类的接口: public interface SaleComputer { public S ...
- java 代理模式 总结
1.前言 最近舍友去面试遇到了关于java代理模式的问题. 我虽然知道怎么使用,但是没有做过正经的总结,因此有了这篇随笔,好好总结一下三大代理模式底层原理. 事实上,在开发项目的时候,基本用不上代理, ...
- 浅谈java代理模式
讲解java代理模式 目录 讲解java代理模式 何谓代理模式 静态代理 动态代理 JDK动态代理 CGLIB动态代理 何谓代理模式 代理模式,即Proxy Pattern,23种java常用设计模式 ...
- java 代理模式(静态代理、动态代理、Cglib代理) 转载
Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩 ...
- java 代理模式-静态代理与动态代理
最近在研究SpringAOP,当然要学习AOP就要知道这么健硕.强大的功能的背后究竟隐藏着怎样不可告人的“秘密”?? 接下来就是查阅了许多资料详细的研究了一下Java的代理模式,感觉还是非常非常重要的 ...
- Java代理模式/静态代理/动态代理
代理模式:即Proxy Pattern,常用的设计模式之一.代理模式的主要作用是为其他对象提供一种代理以控制对这个对象的访问. 代理概念 :为某个对象提供一个代理,以控制对这个对象的访问. 代理类和委 ...
- JAVA代理模式与动态代理模式
1.代理模式 所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用.代理模式给某 ...
随机推荐
- codeforces_1066_B.Heaters
题意:一个数组只含有0或1,1表示该元素可以覆盖其自身.左边r-1个元素和右边r-1个元素,问最少保留多少个1元素可以覆盖整个数组. 思路:一个指针指向当前未被覆盖的最左边的元素下标,每次找离它最远且 ...
- laravel学习:php写一个简单的ioc服务管理容器
php写一个简单的ioc服务管理容器 原创: 陈晨 CoderStory 2018-01-14 最近学习laravel框架,了解到laravel核心是一个大容器,这个容器负责几乎所有服务组件的实例化以 ...
- Python2和Python3除法
Python2和Python3除法 Python2除法:/,//,% "/":整数相除,向下取整:浮点数相除,结果包含小数(类似1/2,想保留小数应该写成1.0/2或者1*1. ...
- gprc-java与golang分别实现服务端,客户端,跨语言通信(一.java实现)
1.在pom中引入 <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-netty< ...
- Bullet:MySQL增强半同步参数rpl_semi_sync_master_wait_point值AFTER_SYNC和AFTER_COMMIT的对比实验
MySQL 5.7.22启用增强半同步复制 MySQL对该参数值的描述 Semisync can wait for slave ACKs at one of two points, AFTER_SYN ...
- luogu 2-SAT 问题
题目大意:给出n个bool变量,以及m个条件,条件为x,vx,y,vy,表示 x == vx || y == vy . 求匹配. 题解: 最近新学了一下2-SAT算法.2-SAT指有若干个bool变量 ...
- Python 1-3区分Python文件的两种用途和模块的搜索路径
区分Python文件的两种用途 run.py文件: import m1 m1.py文件: def f1(): print('f1') def f2(): print('f2') #当文件被执行时__n ...
- 启用Windows10的Linux子系统并安装图形界面
前言 目前市面上的PC电脑主要运行着四大类系统,它们分别是微软的Windows.苹果的MacOS.Linux的发行版以及Unix类系统.其中Linux和Unix都是开源的,因此市面出现的众多基于Lin ...
- Yahoo前端优化的35条军规
摘要:无论是在工作中,还是在面试中,web前端性能的优化都是很重要的,那么我们进行优化需要从哪些方面入手呢?可以遵循雅虎的前端优化34条军规,不过现在已经是35条了,所以可以说是雅虎前端优化的35条军 ...
- Web的三大基石
[HTML] 实现了Web页面. [URL] 1.url Uniform Resource Locator的缩写,称为统一资源定位符.通过URL可以访问到互联网上的一个资源.如:图片.视频.网页等.通 ...