`
忆梦竹
  • 浏览: 64789 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

动态代理的幕后

    博客分类:
  • JAVA
阅读更多
这篇文章将这样来组织:
1. 简单的例子展示静态代理和动态代理。
2. 两种代理的区别。
3. 动态代理的幕后。

静态代理的例子:

package com.piedra.proxy;

/**
 *  StaticProxy.java
 */
public class StaticProxy
{
	public static void main(String[] args){		
		MyProxy proxy = new MyProxy(new ConcreteSubject());
		proxy.saySomething("troubler","Hello,Proxy!");
		proxy.saySomething("piedra","Hello,Proxy!");				
	}	
}

abstract class Subject
{
	public abstract void saySomething(String name,String cont);
}

class ConcreteSubject extends Subject
{
	public void saySomething(String name,String cont){
		System.out.println(name + "说:" + cont);
	}
}


class MyProxy
{
	private Subject subject = null;

	public MyProxy(Subject subject){
		this.subject = subject;
	}

	public void saySomething(String name,String cont){
		if(name!=null && !name.equals("troubler")){
			subject.saySomething(name,cont);
		} else {
			System.out.println("Sorry! You are the troulber. You are not allowed to speak.");
		}
	}
}
 

代码解释:
这里我们让MyProxy来代理Subject对象,那么当我们调用MyProxy的saySomething方法的时候,他会先做一些处理,然后再根据需要调用相应的他所代理的对象的方法。如果需要更多代理模式的内容,你可以google下,会有很多好的资料。

动态代理的简单演示:
我在我的第一篇博文中有浅浅的讲解了动态代理的用法
http://yimengzhu.iteye.com/blog/1133359  不过这里我还是简单提下

package com.piedra.proxy;

import java.lang.reflect.*;

public class DynamicProxy
{
	public static void main(String[] args){
		MyTarget target = new MyTarget();//创建一个目标对象,即待会要被代理的对象。
		MyHandler handler = new MyHandler(target);//待会动态代理对象会将任务分发给这个handler对象的invoke方法处理
		Target proxy = (Target)Proxy.newProxyInstance(target.getClass().getClassLoader(),new Class[]{Target.class},handler);
		proxy.saySomething("piedra","hello,dynamic proxy.");
	}
}

interface Target
{
	public void saySomething(String name,String cont);
}

class MyTarget implements Target
{
	public void saySomething(String name,String cont){
		System.out.println(name + "说: " + cont);
	}
}

class MyHandler implements InvocationHandler
{	
	private Object target;

	public MyHandler(Object target){
		this.target = target;
	}

	public Object invoke(Object proxy,Method method,Object[] args)throws Throwable {
		method.invoke(target,args);
		return null;
	}
}


实验截图:








如果你对代理或者动态代理还不是很熟悉,那么你看着可能有点吃力,那么你可能就应该到google上搜索资料好好的学习下了。

接着我将简单说一下我对静态代理和动态代理的区别的看法:
静态代理他要实现跟目标类一样的接口或者抽象类,然后里面需要实现的方法都要你显示的写出来。然而对于动态代理,你却会发现,只需要一个InvocationHandler就可以搞定了。

那么动态代理到底有什么神奇的力量会这么简单?原因是,当我们调用Proxy的newProxyInstance的时候,Proxy内部会帮助我们创建一个代表我们目标对象的代理对象。因为我们传入了我们的目标类说实现的接口,然后我们也传递给他一个ClassLoader,这样JVM就会知道利用那个ClassLoader去装载这个代理的class文件(Proxy帮我们创建的)。
我想这时候你应该已经明白了。真相就是Proxy帮我们创建的代理对象,然后将直接转发给我们的InvocationHandler对象,接着我们就可以在InvocationHandler对象里面的invoke方法里面为所欲为了。

你有没有发现,这样当我们的Target接口里面的方法变了。如果我们还是使用静态代理那么我们的代理对象也要跟着变,但是如果使用动态代理,我们不需要该表代理对象,只需要变化相应的目标对象就可以了。因为在动态代理中代理对象的生成是Proxy自动生成了。(具体使用的技术我还不懂得用)。

尽管这篇文章深度还不够。但是还是谢谢您的阅读。

但愿我的文章的内容对得起您宝贵的时间!

(注:转载请注明出处,爬虫请加个链接再发布,谢谢您的理解!)

GOF设计模式链接:http://download.csdn.net/detail/hhxy_piedra/4184424


  • 大小: 8.2 KB
  • 大小: 15.7 KB
  • 大小: 14.3 KB
0
0
分享到:
评论

相关推荐

    nucypher:分散阈值密码网络,提供用于秘密管理和动态访问控制的接口和运行时

    分散式密码网络,为秘密管理和动态访问控制提供可访问,直观和可扩展的运行时和接口。... 在幕后,NuCypher网络使用阈值代理重新加密方案提供密码访问控制。NuCypher如何工作? 数据所有者爱丽丝(Alice)通过

    代理商的立法修正-研究论文

    它还描述了国会与机构官员之间关于此类修复的幕后,立法后对话,而这种对话通常是公众所看不见的。 该条表明,各机构通常以不透明且受法律框架外部因素驱动的方式来修正立法起草错误。 这些机构立法手段的初衷是...

    Mycroft Core,Mycroft人工智能平台。-Python开发

    目录目录入门使用Mycroft家用设备和帐户管理器在后台运行Mycroft幕后知识配对信息配置使用不带Home API的Mycroft密钥服务在代理后使用Mycroft在代理后使用Mycroft在未经身份验证的代理后使用Mycroft在经过身份验证的...

    logging_frontend_apps:NGINX配置以代理前端应用程序的日志记录功能

    对于服务器到服务器的通信,这发生在封闭的幕后,即。 VPN或防火墙。 对于前端应用程序,必须打开一个开放的端点,这引发了许多安全性问题。 该存储库旨在通过关注现有基础结构的安全性和稳定性来为此类场景提供...

    ComSat:Erlang http,https,http2,quic w socks44a,socks5支持客户端

    ComSat是不可思议的,也不是通用Web协议的幕后客户端。 它也是一个http和socks5代理客户端。 ComSat绝不会自动缓存响应,合并您的请求或参与其他异端。 状态 OTP 20+ 占位符 路线图 Https (从4592613开始隐含的...

    Mycroft Core是组成Mycroft人工智能平台的主要模块-python

    目录 目录 开始运行 Mycroft 使用 Mycroft 家庭设备和客户经理技能 幕后 配对信息配置 使用 Mycroft 不使用 Home API 关键服务 在代理后面使用 Mycroft 在没有身份验证的代理后面使用 Mycroft 在经过身份验证的代理...

    felix:Project Calico的每主机代理Felix,负责对路由和安全策略进行编程

    是Calico项目的幕后公司,负责项目的持续管理。 但是,它对社区的任何成员(个人或组织)开放并参与并贡献代码。 贡献 感谢您考虑为Calico项目做出贡献! 开源项目的成功完全取决于其贡献者的努力,因此,我们确实...

    sjdbcx:[废弃] Spring JDBC 库的轻量级扩展

    这个想法是将 SQL 和映射器信息作为注释提供给 Repository 接口,然后让代理在幕后完成所有 Spring JDBC 工作。 一个示例(从单元测试中提取)如下所示: public interface PersonRepository { static final ...

    kuproxy:Kubernetes 感知 HAproxy

    代理 Kubernetes 感知外部负载均衡器的概念证明。 在幕后使用 HAproxy 进行实际负载平衡。 这个想法是有一个 haproxy,当 Kubernetes pod 上线/下线时,它会自我配置。 现在它只是在 Kubernetes pod 上线/下线时...

    Qt中QString转换成const char * ()、QByteArray等方法

    (代码值大于65535的Unicode字符使用代理项对(即两个连续的QChars)存储。) Unicode是一个国际标准,它支持目前使用的大多数书写系统。它是US-ASCII(ANSI X3.4-1986)和Latin-1(ISO 8859-1)的超集,所有US-...

    网络安全防护技术教案.docx

    它位于内部用户和外部服务之间,代理在幕后处理所有用户和因特网服务之间的通信以代替相互间的直接交谈。 网络安全防护技术教案全文共3页,当前为第3页。网络安全防护技术教案全文共3页,当前为第3页。优点:允许...

    clj-kubernetes-api:Clojure中的Kubernetes API客户端库

    首先,使用kubectl proxy --port=8080运行kubernetes代理。 每个端点函数都返回一个通道。 在幕后,使用了 http客户端。 ( require '[kubernetes.api.v1 :as k8s] '[clojure.core.async :refer [<!!]]) ; ; ...

    grailsSdn4j:Grails 和 spring-data-neo4j 的集成

    这是整合 Grails 和 spring-data-neo4j 的尝试。 具体来说,它尝试使用示例的简化版本问题是 GrailsN4jGraph.java 中的 @Autowire 语句似乎没有被选中... 它还可能与在这种情况下创建 bean 的顺序以及在幕后代理类有关

    控制台:OpenShift群集控制台UI

    幕后发生的事情包括: 在/api/kubernetes下代理Kubernetes API 提供其他非Kubernetes API与集群交互服务所有前端静态资产用户认证快速开始依存关系: > = 10&> = 1.3.2 > = 1.13+ 或以及OpenShift或Kubernetes集群...

    xiaomi-zb2mqtt:使用Zigbee-Shepherd的小米Zigbee至MQTT桥

    小米-zb2mqtt ...配置:目前,您必须编辑index.js并设置您的串行端口和mqtt代理。 运行 /xiaomi-zb2mqtt$ node index.js 要查看幕后发生的情况,请在启用调试的情况下运行它: /xiaomi-zb2mqtt$ DEBU

    arduino-iot-js:Arduino 物联网云 - Javascript SDK

    此 NPM 模块提供与 Arduino IoT Cloud MQTT 代理的交互。 它可以在浏览器和 node.js 中使用 该模块的主要特点是: 使用 WebSocket 连接/断开与 Arduino IoT Cloud Broker 的连接 发送物联网云属性更新 侦听其他...

    cygni-talent-deploy

    通过SSH管理Linux服务器使用systemd管理linux服务管理应用程序机密和令牌保护linux服务器自动化重复性任务目的目的是获得有关幕后连续部署如何工作的知识。 我们将专注于自动化所有任务。 脚本应该是幂等的,这意味...

    socktopus:基于多路径 TCP 的快速 UDP 传输,适用于广域网

    受到利用多个物理接口创建更快通道的启发, socktopus改为使用 TCP '反射器'(通过 、 或应用程序代理服务器)安装在分布在 Internet 上的许多中继系统上。 然后,这些系统用于通过多路径将流传递到其目的地,依靠 ...

    coursetable:为CourseTable网站提供动力的代码

    Crawler :幕后的脚本实际上是从耶鲁大学的网站上获取所有数据的。 此代码位于我们的资料库中。 仓库布局 网站的各种功能分为以下部分: /api :用于后端逻辑的Express服务器。 /frontend :使用React构建的站点...

    paypal-octa-ipn:PayPal的IPN广播器,最多支持八个不同的IPN主机。 以WHMCS为例

    这是一个幕后过程,客户不会注意到任何事情。 问题在于PayPal仅允许一个IPN链接,这意味着您只能使用此PayPal帐户运行一项自动化业务。 请注意,贝宝允许您拥有两个贝宝帐户,一个个人帐户和一个企业帐户。解决方案...

Global site tag (gtag.js) - Google Analytics