Java设计模式之代理模式

简介:
代理模式,定义为,为另一对象提供一个占位符或者替身以控制对这个对象的访问。故代理模式核心思想就是控制对象访问。
使用代理模式创建代理,可以让代表对象控制某一个对象的访问,该被代表对象可以是远程对象,创建开销大的对象或者需要安全控制的对象。
几种常见的代理控制访问方式:
1)远程代理控制访问远程对象
2)虚拟代理控制访问创建开销大的资源
3)保护代理基于权限控制对资源的访问
代理模式的基本类图
152945602.jpg
Proxy和RealSubject都实现了共同的接口,这允许任何客户都可以像处理RealSubject一样处理Proxy
RealSubject通常是真正做事的对象,proxy会控制对RealSubject的访问。
Proxy持有Subject引用,它可以创建RealSubject对象,来将请求转发给Subject
远程代理
远程代理其实就是远程对象在本地代表,或者说是另一个jvm堆上的对象在本jvm堆中的代表。本地代表,指的就是一种可以由本地方法调用的对象,其行为会转发到远程对象中。
在利用远程代理中,客户对象操作的就是远程对象在本地的代理,客户对象所做的就像是在做远程方法调用,但其实只是调用本地堆中的“代理”对象的方法,再由该代理对象处理所有网络通信的底层细节。
为了实现远程代理,调用远程方法,一般我们就利用RMI(Remote Method Invocation),RMI可以让我们找到远程JVM内的对象,并且允许我们调用它们的方法。关于如何实现RMI的,请参见另一个博客介绍,Java远程方法调用RMI的实现
虚拟代理
虚拟代理主要是作为创建开销大的对象的代表,虚拟代理经常直到我们真正需要一个对象的时候才创建它,当对象在创建前和创建中的时候,由虚拟代理来扮演对象的替身。对象创建完后,代理就会将请求直接委托给对象。
保护代理
保护代理,就是根据访问权限决定客户是否可以访问对象的代理。
一般保护代理就是通过动态代理来实现的,现在就主要讨论一下动态代理如何实现及流程。
动态代理
Java.lang.reflect包有对于代理的支持,可以在运行的时候动态创建一个代理类,实现一个或者多个接口,并将方法的调用转发到你所指定的类。在java中创建动态代理,必须要为你要创建的类先定义一个接口。
动态代理类图如下:
184032264.jpg
动态代理过程中,是由java内置的创建一个proxy类,该类同样是实现了Subject接口,由于该代理类是由java动态创建的,不能将逻辑代码放置到Proxy类里面,则就放置到InvocationHandler中,它主要是相应代理的任何调用信息,当代理收到方法调用的时候,都是委托给 InvocationHandler做的。
Proxy 的静态方法
该方法用于获取指定代理对象所关联的调用处理器 
static InvocationHandler getInvocationHandler(Object proxy) 
该方法用于获取关联于指定类装载器和一组接口的动态代理类的类对象 
static Class getProxyClass(ClassLoader loader, Class[] interfaces) 
该方法用于判断指定类对象是否是一个动态代理类 
static boolean isProxyClass(Class cl) 
该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例 
static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
InvocationHandler 的核心方法
第一个参数是代理类实例,第二个参数是被调用的方法对象,第三个方法是调用参数
调用处理器根据这三个参数进行预处理或分派到委托类实例上发射执行 
Object invoke(Object proxy, Method method, Object[] args)
使用 Java 动态代理的具体步骤:
1. 通过实现 InvocationHandler 接口创建自己的调用处理器,并且提供一个方法设置代理类
2. 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
3. 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
4. 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。
动态代理创建实例代码
基类接口
package imitate.proxy.intercepter;
public interface Dog {
void info();
void run();
}
被代理实现类
package imitate.proxy.intercepter;
public class DogImpl  implements Dog{
@Override
public void info() {
// TODO Auto-generated method stub
System.out.println( "可爱的小猎狗");
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println( "疯狂的跑呀跑呀");
}
}
生成代理的类
package imitate.proxy.intercepter;
import java.lang.reflect.Proxy;
//根据目标对象生成一个代理对象
public class MyProxyFactory {

public static Object getProxy(Object obj)
{
//代理的处理类
ProxyHandler proxy= new ProxyHandler();
proxy.setTarget(obj);
//第一个参数用来创建动态代理的对象
//第二个参数代理的接口对象数组
//第三个参数代理包含的处理实例
//返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。此方法相当于: 
return Proxy.newProxyInstance(obj. getClass.getClassLoader(),
obj.getClass().getInterfaces(), proxy);
}
}
代理 调用处理器接口
package imitate.proxy.intercepter;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ProxyHandler  implements InvocationHandler {

//需要被代理的目标对象
private Object target;
//用于设置传入目标对象的方法
public void setTarget(Object obj)
{
this.target=obj;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
Object result= null;
if(method.getName().equals( "info"))
{
System.out.println( "First enter here");
result=method.invoke(target, args);
System.out.println( "Last exit here");
}
else
{
System.out.println( "First other enter here");
result=method.invoke(target, args);
System.out.println( "First other enter here");
}
return result;
}

}
动态代理测试类
package imitate.proxy.intercepter;

public class TestDog {
public static void main(String[] args) {

Dog target= new DogImpl();
Dog dog= null;
//以目标对象创建代理
Object proxy=MyProxyFactory.getProxy(target);
if(proxy  instanceof Dog)
{
dog=(Dog)proxy;
}
dog.info();
}
}


本文转自 zhao_xiao_long 51CTO博客,原文链接:http://blog.51cto.com/computerdragon/1178054

相关文章
|
6天前
|
设计模式 Java
Java中的设计模式及其应用场景解析
Java中的设计模式及其应用场景解析
|
3天前
|
设计模式 测试技术 Python
《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
【7月更文挑战第10天】Page Object Model (POM)是Selenium自动化测试中的设计模式,用于提高代码的可读性和维护性。POM将每个页面表示为一个类,封装元素定位和交互操作,使得测试脚本与页面元素分离。当页面元素改变时,只需更新对应页面类,减少了脚本的重复工作和维护复杂度,有利于团队协作。POM通过创建页面对象,管理页面元素集合,将业务逻辑与元素定位解耦合,增强了代码的复用性。示例展示了不使用POM时,脚本直接混杂了元素定位和业务逻辑,而POM则能解决这一问题。
23 6
|
1天前
|
设计模式 Java 测试技术
《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
【7月更文挑战第12天】在本文中,作者宏哥介绍了如何在不使用PageFactory的情况下,用Java和Selenium实现Page Object Model (POM)。文章通过一个百度首页登录的实战例子来说明。首先,创建了一个名为`BaiduHomePage1`的页面对象类,其中包含了页面元素的定位和相关操作方法。接着,创建了测试类`TestWithPOM1`,在测试类中初始化WebDriver,设置驱动路径,最大化窗口,并调用页面对象类的方法进行登录操作。这样,测试脚本保持简洁,遵循了POM模式的高可读性和可维护性原则。
11 2
|
4天前
|
设计模式 安全 Java
Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
15 1
|
5天前
|
设计模式 Java 数据库连接
Java中的设计模式在实际项目中的应用
Java中的设计模式在实际项目中的应用
|
12天前
|
设计模式 消息中间件 负载均衡
实现可扩展和可靠的分布式系统的Java设计模式
实现可扩展和可靠的分布式系统的Java设计模式
|
11天前
|
设计模式 Java 数据安全/隐私保护
Java中的设计模式:从入门到精通
Java中的设计模式:从入门到精通
|
12天前
|
设计模式 缓存 算法
编写高效的Java工具类:实用技巧与设计模式
编写高效的Java工具类:实用技巧与设计模式
|
2天前
|
设计模式 Java 测试技术
《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
【7月更文挑战第11天】页面对象模型(POM)通过Page Factory在Java Selenium测试中被应用,简化了代码维护。在POM中,每个网页对应一个Page Class,其中包含页面元素和相关操作。对比之下,非POM实现直接在测试脚本中处理元素定位和交互,代码可读性和可维护性较低。
|
4天前
|
存储 设计模式 Java
Java面试题:解释代理模式的概念,并举例说明其应用场景。
Java面试题:解释代理模式的概念,并举例说明其应用场景。
6 0

热门文章

最新文章