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.代理模式 所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用.代理模式给某 ... 
随机推荐
- CAD参数绘制圆弧(com接口)
			在CAD设计时,需要绘制圆弧,用户可以在图面点圆弧起点,圆弧上的一点和圆弧的终点,这样就绘制出圆弧. 主要用到函数说明: _DMxDrawX::DrawArc2 由圆弧上的三点绘制一个圆弧.详细说明如 ... 
- PHP与MySQL的亲密接触
			PHP与MySQL的亲密接触 此篇文章前,你应该先做好一些准备工作 1.建好一个mysql数据库,记住servername,username,password 三者缺一不可. 2.在数据库创建cr ... 
- seq2seq(1)- EncoderDecoder架构
			零 seq2seq是从序列到序列的学习过程,最重要的是输入序列和输出序列是可变长的,这种方式就非常灵活了,典型的机器翻译就是这样一个过程. 一 最基本的seq2seq网络架构如下所示: 可以看到,en ... 
- 微信小程序(template的使用)
			小程序的template是一个模版功能,在创建一个template后,其他的页面可以引用,相比component较简单.方便! template只需要两个文件,一个wxss文件和wxml文件,也只有这 ... 
- enote笔记法的思考(ver0.2)
			章节:enote笔记法的思考 enote笔记法,它是一种独特的文本标记方式与呈现方式.这一整套系统的记笔记的方法,它能够帮助我们对文本内容(例如,其中的概念.观点.思想等)更加直观和条理地进行理性 ... 
- 零基础入门学习Python(33)--异常处理:你不可能总是对的2
			知识点 异常处理 捕捉异常可以使用try/except语句. try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理. 如果你不想在异常发生时结束你的程序,只需 ... 
- flask 开发配置
			flask 开发配置 一:在虚拟机里面安装ubuntu系统.略 二: apt install python3-pip #安装pip, pip3 install --upgrade pip 三: pip ... 
- ubuntu 14.04上源码编译安装php7
			wget https://downloads.php.net/~ab/php-7.0.0alpha2.tar.bz2 //用winscp把下载好的文件上传到网站中 tar jxf php-7.0.0a ... 
- POJ1013称硬币【枚举】
			Counterfeit Dollar Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 52474 Accepted: 16 ... 
- 有三个数a,b,c要求按大小顺序将其输出<if,else语句的学习>
			#include <stdio.h> /* 有三个数a,b,c要求按大小顺序将其输出 ----------soulsjie 20170525------ */ void main(){ i ... 
