静态代理与动态代理二

简介:
           

   动态代理的实现是基于java的三种API的,下面先来介绍一下:

           1、java.lang.reflect.Proxy

            这是 Java 动态代理机制生成的所有动态代理类的父类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象。          

<span style="font-size:14px;">// 方法 1: 该方法用于获取指定代理对象所关联的调用处理器
static InvocationHandler getInvocationHandler(Object proxy) 

// 方法 2:该方法用于获取关联于指定类装载器和一组接口的动态代理类的类对象
static Class getProxyClass(ClassLoader loader, Class[] interfaces) 

// 方法 3:该方法用于判断指定类对象是否是一个动态代理类
static boolean isProxyClass(Class cl) 

// 方法 4:该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例
static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 
</span>
          当然啦,我觉得这些方法不需要记住,只需要在用的时候去查API,多用也就容易上手啦~~

         2、java.lang.reflect.InvocationHandler

           这是调用处理器接口,它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。每次生成动态代理类对象时都要指定一个对应的调用处理器对象。 
       

<span style="font-size:14px;">// 该方法负责集中处理动态代理类上的所有方法调用。第一个参数既是代理类实例,第二个参数是被调用的方法对象
// 第三个方法是调用参数。调用处理器根据这三个参数进行预处理或分派到委托类实例上反射执行
Object invoke(Object proxy, Method method, Object[] args) 
</span>
         3、java.lang.ClassLoader(看到java类装载器,突然想到drp的时候还提到了tomcat类装载器)

        这是类装载器类,负责将类的字节码装载到 Java 虚拟机(JVM)中并为其定义类对象,然后该类才能被使用。Proxy 静态方法生成动态代理类同样需要通过类装载器来进行装载才能使用,它与普通类的唯一区别就是其字节码是由 JVM 在运行时动态生成的而非预存在于任何一个 .class 文件中。
每次生成动态代理类对象时都需要指定一个类装载器对象 。

       下面用和上边相似的例子说一下:

       1、  创建一个处理器,用来动态生成代理

<span style="font-size:14px;">/****************创建自己的调用处理器 *****************/
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;


public class TestInvocationHandler implements <span style="color:#ff0000;">InvocationHandler</span> {

	//代理类持有委托类的引用
	private Object delegate;
	
	public TestInvocationHandler(Object delegate){
		this.delegate=delegate;
	}
	
	/**
	 * @param proxy:代理类实例
	 * @param method:被调用的方法
	 * @param args:参数
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		long stime = System.currentTimeMillis();   
		  //利用反射机制将请求分派给委托类处理。Method的invoke返回Object对象作为方法执行结果。  
		 //因为示例程序没有返回值,所以这里忽略了返回值处理  
		 method.invoke(delegate, args);  
		 long ftime = System.currentTimeMillis();   
		 System.out.println("执行任务耗时"+(ftime - stime)+"毫秒");  
		   
		 return null;  

	}

}
</span>
          2、
      
<span style="font-size:14px;">/*************生成动态代理对象的工厂,工厂方法列出了如何生成动态代理类对象的步骤。***************/
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;




public class DynamicTestFactory {
	
	
	public  static ITest getInstance() {
		ITest delegate=new Test();
		InvocationHandler testInvocationHandler=new TestInvocationHandler(delegate);
		ITest proxy = null;  
		 proxy = (ITest)Proxy.newProxyInstance(delegate.getClass().getClassLoader(),delegate.getClass().getInterfaces(),testInvocationHandler);  
		 return proxy;  

	}
}
</span>
         3、客户端调用工厂,隐藏方法          

<span style="font-size:14px;">public class DynamicClient {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ITest delegate=DynamicTestFactory.getInstance();
		delegate.addStudent("坏学生");

	}

}
</span>

         下面是动态代理的类继承图:

          
         由图可见,Proxy 类是它的父类,这个规则适用于所有由 Proxy 创建的动态代理类。而且该类还实现了其所代理的一组接口,这就是为什么它能够被安全地类型转换到其所代理的某接口的根本原因。 

        那动态代理有哪些优点呢?如果认真看过前面对静态代理的解释的话,我想,动态代理的优点就是避免了静态代理的缺点。

        动态代理接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。

         Proxy 已经设计得非常优美,但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持 interface 代理的桎梏,因为它的设计注定了这个遗憾。回想一下那些动态生成的代理类的继承关系图,它们已经注定有一个共同的父类叫 Proxy。Java 的继承机制注定了这些动态代理类们无法实现对 class 的动态代理,原因是多继承在 Java 中本质上就行不通。 
       
 




相关文章
|
2月前
|
数据采集 监控 安全
代理IP全解析:从原理到自建代理池的实战指南
代理IP如同网络世界的“隐形斗篷”,能隐藏真实身份,保护隐私,突破访问限制,提升数据抓取效率。本文详解代理IP的核心价值、自建代理池的技术方案、运维策略及实战应用,助你掌握数字时代的生存技能。
249 0
|
4月前
|
数据采集 人工智能 安全
动态IP代理与静态IP代理的深度解析及国内服务评估
动态IP代理与静态IP代理在技术原理、性能表现及应用场景上各有千秋。动态IP通过IP池轮换实现高频短时访问,适合预算有限的企业,成本低、效率高;静态IP采用固定分配模式,连接稳定且安全性强,适配长期会话需求。国内服务商分三大梯队,提供多样化方案。选型需综合业务需求、安全要求与成本预算,未来技术发展将推动代理服务更高效、可信。企业应根据解析评估,选择适配方案以提升竞争力。
210 0
|
6月前
|
数据采集 存储 缓存
Python爬虫与代理IP:高效抓取数据的实战指南
在数据驱动的时代,网络爬虫是获取信息的重要工具。本文详解如何用Python结合代理IP抓取数据:从基础概念(爬虫原理与代理作用)到环境搭建(核心库与代理选择),再到实战步骤(单线程、多线程及Scrapy框架应用)。同时探讨反爬策略、数据处理与存储,并强调伦理与法律边界。最后分享性能优化技巧,助您高效抓取公开数据,实现技术与伦理的平衡。
241 4
|
22天前
|
消息中间件 存储 Java
RabbitMQ 和 Spring Cloud Stream 实现异步通信
本文介绍了在微服务架构中,如何利用 RabbitMQ 作为消息代理,并结合 Spring Cloud Stream 实现高效的异步通信。内容涵盖异步通信的优势、RabbitMQ 的核心概念与特性、Spring Cloud Stream 的功能及其与 RabbitMQ 的集成方式。通过这种组合,开发者可以构建出具备高可用性、可扩展性和弹性的分布式系统,满足现代应用对快速响应和可靠消息传递的需求。
RabbitMQ 和 Spring Cloud Stream 实现异步通信
|
10月前
|
数据采集
动态代理与静态代理在爬虫解析的优缺点
随着科技和互联网的发展,越来越多企业需要使用代理进行数据抓取。本文介绍了HTTP动态代理与静态代理的区别,帮助您根据具体需求选择最佳方案。动态代理适合大规模、高效率的爬取任务,但稳定性较差;静态代理则适用于小规模、高稳定性和速度要求的场景。选择时需考虑目标、数据量及网站策略。
167 4
|
5月前
|
人工智能 监控 API
全网跪求的抢票神器!用 CodeBuddy 联动魔搭 MCP,我把 12306 抢票系统玩明白了
CodeBuddy 作为智能编程领域的佼佼者,无需用户具备深厚的编程知识,就能依据用户需求迅速生成高效代码。在票务信息获取方面,它巧妙地构建起与两款 MCP 顺畅交互的桥梁。通过简洁直观的指令输入,CodeBuddy 将用户对票务信息的需求精准转化为机器可理解的语言,为后续获取信息的流程奠定坚实基础。
361 2
|
消息中间件 设计模式 缓存
什么是动态代理?还有什么代理类型?
什么是动态代理?还有什么代理类型?
157 2
|
12月前
|
缓存 负载均衡 安全
正向代理和反向代理
本文详细介绍了代理和反向代理的概念及应用场景。代理作为一种中间人服务,可细分为正向代理与反向代理。前者位于客户端与网络间,有助于匿名浏览、访问控制、缓存加速及增强安全性;后者则位于网络与服务器间,主要用于负载均衡、缓存、安全性提升、SSL终止及内容过滤等。两者各有侧重,可根据具体需求选择使用。例如,Squid 是常用的正向代理框架,而 Nginx 则常用于反向代理。了解并合理运用两者,能有效提升网络性能与安全性。
613 4
|
Web App开发 缓存 安全
什么是HTTP代理?HTTP代理的作用?HTTP代理怎么设置?
HTTP代理是位于客户端和服务器之间的中间服务器,用于拦截并转发网络请求和响应。它能增强安全、缓存内容提升性能、访问受限资源。代理分为正向、反向和透明三种类型。设置HTTP代理涉及选择代理服务器,配置客户端的网络设置,或通过代理IP提供商获取服务。在Windows和macOS中,可在系统设置里配置代理;在Chrome和Firefox浏览器中,可通过浏览器设置进行代理配置。
|
Java 开发者 Spring
什么是静态代理和动态代理,两者的区别(笔记)
什么是静态代理和动态代理,两者的区别(笔记)
343 0