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 代理模式详解,布布扣,bubuko.com

时间: 2024-10-23 02:00:03

java 代理模式详解的相关文章

设计模式 - 代理模式(proxy pattern) 未使用代理模式 详解

代理模式(proxy pattern) 未使用代理模式 详解 本文地址: http://blog.csdn.net/caroline_wendy 部分代码参考: http://blog.csdn.net/caroline_wendy/article/details/37698747 如果需要监控(monitor)类的某些状态, 则需要编写一个监控类, 并同过监控类进行监控. 但仅仅局限于本地, 如果需要远程监控, 则需要使用代理模式(proxy pattern). 具体方法: 1. 类中需要提供

Docker Kubernetes Service 网络服务代理模式详解

Docker Kubernetes  Service 网络服务代理模式详解 Service service是实现kubernetes网络通信的一个服务 主要功能:负载均衡.网络规则分布到具体pod 注:kubernetes deployment服务分配服务器负载均衡VIP只能NODE节点单独访问,这里需要外网用户可以放问到容器内,这里就需要用到service. 网络代理模式 kube-proxy v1.0中只支持userspace模式,在v1.1中,添加了iptables代理,在v1.2开始ip

(二) 代理模式详解(包含原理详解)

转载:http://www.cnblogs.com/zuoxiaolong/p/pattern3.html 本章接着讨论第二种要介绍的设计模式,代理模式. LZ不希望写的东西与网络上的资料千篇一律,所以这一系列不会像很多典型文章一章,只是列出这个模式的定义以及一堆适用的情况,然后就是一堆这个模式的各个角色,对于这种罗列LZ并不反对,相比之下会比较清晰,但是如果脱离了实际,就会导致看的人特别是初学者觉得设计模式很陌生很遥远. LZ并不反对这种教学式的标准模式,但说实话,LZ本人看这种帖子从来都感觉

java中设计模式详解

一.设计模式的分类 总体来说设计模式分为三大类: (1)创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. (2)结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. (3)行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 其实还有两类:并发型模式和线程池模式.用一个图片来整体描述一下: 二.设计模式的六大原则 1.开闭原则

代理模式详解

什么是代理模式 代理模式是对象的结构模式.代理模式为其他对象提供一种代理以控制对这个对象的访问. 简单来说,在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 举个例子 我们打算结婚,但是婚礼的细节我们不想管,这时候我们找到婚庆公司,让他们帮我们包揽婚礼的细节,这就是"代理模式".既然是代理模式,那么就应该有一个代理角色和真实角色.例子中的"我们"就是真实角色,"婚庆公司"就是代理角色. 我

【设计模式】代理模式详解

前言 博主只是一名大三学生,文章内容难免有不足之处,欢迎批评指正. 正文 转载请注明出处: http://blog.csdn.net/h28496/article/details/46707621 发 表 时 间: 2015年7月1日 什么是代理模式? 为其他对象提供一种代理,用来控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 代理模式常被分为远程代理.虚拟代理.保护代理等等. 代理模式的结构 UML类图 角色介

五、代理模式详解

7.代理模式 7.1.课程目标 1.掌握代理模式的应用场景和实现原理. 2.了解静态代理和动态代理的区别. 3.了解CGLib和JDK Proxy的根本区别. 4.手写实现定义的动态代理. 7.2.内容定位 都知道 SpringAOP 是用代理模式实现,到底是怎么实现的?我们来一探究竟,并且自己仿真手写 还原部分细节. 7.3.代理模式定义 代理模式(ProxyPattern)是指为其他对象提供一种代理,以控制对这个对象的访问,属于结构型模式. 在某些情况下,一个对象不适合或者不能直接引用另一个

火热的足球广告平台代理模式详解

什么是足球广告平台? 足球广告平台是一款连接广告与受众的新型平台. 以往广告通常需要找到一个拥有大量流量的媒体,一般有报纸.电视台.微博大v.自媒体大v等.这类流量有个共同点,就是广告主出相应费用,让他们一次或者多次发布软文或者硬广,中间或许还要参入一些策划团队来实现文案与活动的策划.这类媒体普遍存在转化率低导致的性价比不高.另一种就是类似百度这类搜索引擎的"按点击付费",这类精准客户多,几乎点击的人都是潜在客户,转化率普遍比较高.所以性价比出众.足球广告在这样的一种排名机制上进化,自

好程序员Java教程Java动态代理机制详解

好程序员Java教程Java动态代理机制详解:在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的.首先我们先来看看java的API帮助文档是怎么样对这两个类进行描述的: InvocationHandler: 1InvocationHandler is the interface implemented by the invocation handle