代理模式是我们比较常用的设计模式之一。其中新思想是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信,代理模式一般涉及到的角色有:

抽象角色:声明真实对象和代理对象的共同接口;
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
以下以发送消息为例来说明一个简单的代理模式的基本实现:
首先明确目的:有一条消息,需要把这个消息发送出去,根据这个目的定义对应接口MessageHandler。需要的附加操作:假设需要验证消息的长度不能超过指定长度并且不能为空,并且我们需要统计相关信息发送到次数,超过指定的次数我们需要输出警报。我们通过代理模式来实现这个附加的操作。下面为对应的类关系图及示例代码。
//接口定义
public interface MessageHandler {
public void sendMessage(String msg);
}
//通过Email方式发送消息的实现类
public class EmailMessage implements MessageHandler {
@Override
public void sendMessage(String msg) {
// TODO Auto-generated method stub
System.out.println(msg+" send!!");
}
}
//消息处理的代理类
public class MessageProxy implements MessageHandler {
private static int count;
private MessageHandler emailMsg;
@Override
public void sendMessage(String msg) {
// TODO Auto-generated method stub
if(checkMessage(msg))
{
if(emailMsg==null) emailMsg=new EmailMessage();
count++;
emailMsg.sendMessage(msg);
System.out.println("Message sent:"+count);
}
}
private boolean checkMessage(String msg) {
return msg != null && msg.length() > 10;
}
}
//调用类
public class MainClass {
private static void runProxy(MessageHandler handler)
{
handler.sendMessage("message for test");
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
runProxy(new EmailMessage());
System.out.println("++++++++++++++++Pjroxy++++++++++++++++++");
runProxy(new MessageProxy());
}
}
//输出
message for test send!!
++++++++++++++++Pjroxy++++++++++++++++++
message for test send!!
Message sent:1
在例子中我们可以方便的在消息发送过程中添加各种需要的附加处理方式,也能方便的替换消息的处理方式,如将通过Email发送消息替换为通过短信发送消息,而调用方不会有丝毫察觉!在任何你想要将一些额外操作分离到具体对象之外,特别是希望能够很容易做出修改,或者想在具体对象的方法执行前插入一些额外操作的时候,代理就显得十分有用!
动态代理
Java中动态代理机制的引入使得代理模式的思想更加完善与进步,它允许动态的创建代理并支持对动态的对所代理的方法进行调用。Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:
(1). Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组。这个抽象方法在代理类中动态实现。
(2).Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容:
Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。
Static Class getProxyClass (ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。
Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。
所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。 下面我们通过动态代理来重新实现上面发送信息的例子!
在上面的例子基础上,我们先添加一个通过短信来发送消息的处理类:
public class SmsMessage implements MessageHandler {
@Override
public void sendMessage(String msg) {
// TODO Auto-generated method stub
System.out.println("SMS Message :" + msg+" sent !");
}
}
//动态代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicMessageProxy implements InvocationHandler {
private static int count;
private MessageHandler msgHandler;
public DynamicMessageProxy(MessageHandler handler) {
msgHandler = handler;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
System.out.println("++++++++=============+++++++++");
System.out.println("proxy:" + proxy.getClass());
System.out.println("method:" + method);
System.out.println("++++++++=============+++++++++");
if (args != null && args.length == 1 && checkMessage((String) args[0])) {
count++;
System.out.println("Message sent:" + count);
return method.invoke(msgHandler, args);
}
return null;
}
private boolean checkMessage(String msg) {
return msg != null && msg.length() > 10;
}
}
//下面是调用
import java.lang.reflect.Proxy;
public class MainClass {
private static void runProxy(MessageHandler handler) {
handler.sendMessage("message for test");
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// runProxy(new EmailMessage());
// System.out.println("++++++++++++++++Proxy++++++++++++++++++");
// runProxy(new MessageProxy());
MessageHandler handler = new EmailMessage();
runProxy(handler);
MessageHandler proxy = (MessageHandler) Proxy.newProxyInstance(
MessageHandler.class.getClassLoader(),
new Class[] { MessageHandler.class }, new DynamicMessageProxy(
handler));
runProxy(proxy);
System.out.println("++++++++++++++++++++++++++++++++++");
// 短信方式
handler = new SmsMessage();
runProxy(handler);
proxy = (MessageHandler) Proxy.newProxyInstance(MessageHandler.class
.getClassLoader(), new Class[] { MessageHandler.class },
new DynamicMessageProxy(handler));
runProxy(proxy);
}
}
//下面为以上方法的输出:
message for test send!!
++++++++=============+++++++++
proxy:class $Proxy0
method:public abstract void MessageHandler.sendMessage(java.lang.String)
++++++++=============+++++++++
Message sent:1
message for test send!!
++++++++++++++++++++++++++++++++++
SMS Message :message for test sent !
++++++++=============+++++++++
proxy:class $Proxy0
method:public abstract void MessageHandler.sendMessage(java.lang.String)
++++++++=============+++++++++
Message sent:2
SMS Message :message for test sent !
以上例子中,通过调用Proxy.newProxyInstance方法创建动态代理对象,该方法需要传入一个 类加载器、一组希望代理实现的接口列表、InvocationHandler 接口的一个具体实现。动态代理可以将所有调用重定向到调用处理器,通常我们会向该处理器传递一个时间对象的引用。invoke()方法中传递进来了代理对象,当你需要区分请求来源时这是非常有用的,例如你可以通过判断传入的方法名屏蔽掉某些方法的执行!动态代理机制并不是会很频繁使用的方法,它通常用来解决一些特定情况下的问题,因此不要盲目的为了使用而使用,要根据自己的实际需求来决定!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# Java
# 代理模式
# Java代理模式实例详解【静态代理与动态代理】
# Java代理模式实例分析
# 23种设计模式(7) java代理模式
# 轻松掌握Java代理模式
# java代理模式与动态代理模式详解
# Java基础之让你彻底搞懂代理模式
# Java通俗易懂系列设计模式之代理模式
# Java线程创建静态代理模式代码实例
# Java简单实现动态代理模式过程解析
# 浅谈JAVA设计模式之代理模式
# Java设计模式之代理模式详解
# 发送消息
# 涉及到
# 你必须
# 自己的
# 这是
# 是在
# 来了
# 会有
# 你可以
# 第一个
# 是这样
# 基础上
# 都能
# 是指
# 也能
# 当你
# 其他的
# 而在
# 你想
# 很容易
相关文章:
香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南
招商网站制作流程,网站招商广告语?
如何用花生壳三步快速搭建专属网站?
建站之星如何快速更换网站模板?
建站之星代理商如何保障技术支持与售后服务?
建站主机选虚拟主机还是云服务器更好?
建站之星在线版空间:自助建站+智能模板一键生成方案
如何选择适合PHP云建站的开源框架?
如何通过商城免费建站系统源码自定义网站主题?
已有域名如何免费搭建网站?
免费网站制作appp,免费制作app哪个平台好?
公司网站制作价格怎么算,公司办个官网需要多少钱?
如何快速使用云服务器搭建个人网站?
建站主机服务器选型指南与性能优化方案解析
如何通过西部建站助手安装IIS服务器?
宿州网站制作公司兴策,安徽省低保查询网站?
如何用免费手机建站系统零基础打造专业网站?
香港服务器租用每月最低只需15元?
香港服务器选型指南:免备案配置与高效建站方案解析
建站之星多图banner生成与模板自定义指南
如何通过多用户协作模板快速搭建高效企业网站?
无锡制作网站公司有哪些,无锡优八网络科技有限公司介绍?
如何在云指建站中生成FTP站点?
活动邀请函制作网站有哪些,活动邀请函文案?
存储型VPS适合搭建中小型网站吗?
,南京靠谱的征婚网站?
*服务器网站为何频现安全漏洞?
如何注册花生壳免费域名并搭建个人网站?
网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?
建站主机选购指南:核心配置与性价比推荐解析
高端智能建站公司优选:品牌定制与SEO优化一站式服务
公司网站的制作公司,企业网站制作基本流程有哪些?
如何彻底删除建站之星生成的Banner?
香港服务器WordPress建站指南:SEO优化与高效部署策略
如何快速打造个性化非模板自助建站?
,想在网上投简历,哪几个网站比较好?
网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?
如何在自有机房高效搭建专业网站?
零基础网站服务器架设实战:轻量应用与域名解析配置指南
建站主机选购指南与交易推荐:核心配置解析
5种Android数据存储方式汇总
如何生成腾讯云建站专用兑换码?
如何高效搭建专业期货交易平台网站?
建站IDE高效指南:快速搭建+SEO优化+自适应模板全解析
建站主机选哪家性价比最高?
制作网页的网站有哪些,电脑上怎么做网页?
建站主机类型有哪些?如何正确选型
广德云建站网站建设方案与建站流程优化指南
七夕网站制作视频,七夕大促活动怎么报名?
网站制作公司排行榜,四大门户网站排名?
*请认真填写需求信息,我们会在24小时内与您取得联系。