博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
代理设计模式
阅读量:4072 次
发布时间:2019-05-25

本文共 3236 字,大约阅读时间需要 10 分钟。

代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。

基础代理实现模型

以下是实现一个用户上网的代理实现:

//定义Network接口interface Network{
//定义浏览的抽象方法 public void browse();}//真实上网操作class RealCustomer implements Network{
@Override public void browse() {
//覆写抽象方法 System.out.println("上网浏览信息"); } }//代理上网class Proxy implements Network{
private Network network; //设置代理的真实操作 public Proxy(Network network) { //设置代理的子类 this.network = network; } //与具体上网相关的操作 public void check(){ System.out.println("用户是否合法"); } @Override public void browse() { this.check();//可以调用多个与具体业务相关的操作 this.network.browse();//调用真实上网操作 }}public class ProxyGOF {
public static void main(String[] args) { //定义接口对象 Network network = null; //实例化代理,同时传入代理的真实操作 network = new Proxy(new RealCustomer()); network.browse();//客户实现上网功能,不关心代理是如何实现的 }}

这种代理只能实现一个接口的子类对象,无法实现多接口的子类对象。需要使用动态代理来解决这种问题。

动态代理设计模型

想要实现动态代理设计的实现,代理类不再局限于具体实现某一个具体的类。
在Java核心API中提供了一个java.lang.reflect.InvocationHandler接口。

public interface InvocationHandler {
/** *处理代理实例上的方法调用并返回结果。 当在与之关联的代理实例上调用方法时,将在调用处理程序中调用此方法。 * @param proxy 调用该方法的实例 * @param method 返回的是被调用的方法对象,取得了Method对象意味着可以使用invoke()反射调用方法 * @param args 表示方法中接收到的参数 * @return 方法的返回值 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;}

如果要想进行对象的绑定,那么就需要使用到一个Proxy的程序类,这个程序类的主要功能是可以绑定所有的你需要绑定的接口子类的对象,而且这些对象都是根据接口自动创建的,该类中有一个动态创建绑定对象的方法:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) IllegalArgumentException

动态代理的实现实例:

package com.czl.gof;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;interface ISubject{
//代理设计的核心在于有一个核心接口操作 public void browse(String user,String pass);//用户上网是核心业务}class RealSubject implements ISubject{
//真实用户实现上网功能 @Override public void browse(String user, String pass) { System.out.println("[userName] : " + user + ", [password] :" + pass); } }class DynamicProxy implements InvocationHandler{ private Object target;//绑定任意的接口对象,使用Object类型 /** * 实现真实对象的绑定处理,同时返回代理对象 * @param target * @return 返回一个代理对象(这个对象是根据接口定义动态创建形成的代理对象) */ public Object bind(Object target) { this.target = target; //返回一个代理对象。 //target.getClass().getClassLoader()表示接口对象的类加载路径; //target.getClass().getInterfaces()表示接口对象数,是一个数组对象; //this表示当前对象,在次类中指的是DynamicProxy类对象 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } //定义代理实现的方法 public void register(){ System.out.println("register"); } public void logout(){ System.out.println("log out"); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { this.register();//调用登记方法 //反射调用实现真实主题的方法 Object ret = method.invoke(this.target, args); this.logout();//调用登出方法 return ret; }}public class ProxyGOF {
public static void main(String[] args) { ISubject subject = (ISubject) new DynamicProxy().bind(new RealSubject()); subject.browse("tom", "123"); }}

转载地址:http://jdrji.baihongyu.com/

你可能感兴趣的文章
mongodb 命令
查看>>
MongoDB基本使用
查看>>
mongodb管理与安全认证
查看>>
nodejs内存控制
查看>>
nodejs Stream使用中的陷阱
查看>>
MongoDB 数据文件备份与恢复
查看>>
数据库索引介绍及使用
查看>>
MongoDB数据库插入、更新和删除操作详解
查看>>
MongoDB文档(Document)全局唯一ID的设计思路
查看>>
mongoDB简介
查看>>
Redis持久化存储(AOF与RDB两种模式)
查看>>
memcached工作原理与优化建议
查看>>
Redis与Memcached的区别
查看>>
redis sharding方案
查看>>
程序员最核心的竞争力是什么?
查看>>
Node.js机制及原理理解初步
查看>>
linux CPU个数查看
查看>>
分布式应用开发相关的面试题收集
查看>>
简单理解Socket及TCP/IP、Http、Socket的区别
查看>>
利用HTTP Cache来优化网站
查看>>