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.代理模式 所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用.代理模式给某 ...
随机推荐
- 转:谈谈iOS中粘性动画以及果冻效果的实现
在最近做个一个自定义PageControl——KYAnimatedPageControl中,我实现了CALayer的形变动画以及CALayer的弹性动画,效果先过目: 先做个提纲: 第一个分享的主题是 ...
- clusterdb - 对一个PostgreSQL数据库进行建簇
SYNOPSIS clusterdb [ connection-option...] [ --table | -t table] [ dbname] clusterdb [ connection-op ...
- python 实现代理服务器
# encoding:utf-8 import socket import thread import re def getAddr(d): a = re.search("Host: (.* ...
- HTTP的缺点与HTTPS
a.通信使用明文不加密,内容可能被窃听 b.不验证通信方身份,可能遭到伪装 c.无法验证报文完整性,可能被篡改 HTTPS就是HTTP加上加密处理(一般是SSL安全通信线路)+认证+完整性保护
- SQL函数解释(待补)
1.SQL— CONCAT(字符串连接函数) 有的时候,我们有需要将由不同栏位获得的资料串连在一起.每一种资料库都有提供方法来达到这个目的: MySQL: CONCAT() Oracle: CONCA ...
- 用js 转化大小写
function capitalize(string){ var words =string.split(" "); for(var i=0;i<words.length;i ...
- Educational Codeforces Round 58 (Rated for Div. 2) (前两题题解)
感慨 这次比较昏迷最近算法有点飘,都在玩pygame...做出第一题让人hack了,第二题还昏迷想错了 A Minimum Integer(数学) 水题,上来就能做出来但是让人hack成了tle,所以 ...
- 笔试算法题(06):最大连续子数组和 & 二叉树路径和值
出题:预先输入一个整型数组,数组中有正数也有负数:数组中连续一个或者多个整数组成一个子数组,每个子数组有一个和:求所有子数组中和的最大值,要求时间复杂度O(n): 分析: 时间复杂度为线性表明只允许一 ...
- navicat连接mysql8报错,错误提示为1251,原因及解决步骤
一.错误原因: MySQL8.0版本的加密方式和MySQL5.0的不一样,连接会报错. 二.解决步骤: 1.在linux虚拟机上登录mysql 2.更改加密方式: ALTER USER 'root'@ ...
- node new Buffer()详解
new Buffer(size) size {Number} 分配一个 size 字节大小的新 Buffer.size 必须小于等于 require('buffer').kMaxLength(在64位 ...