`

代理模式(含动态代理讲解)【Spring AOP实质】

    博客分类:
  • java
阅读更多
注意:Struts2其实本身就是基于代理实现的,不是去真正执行Action里面的代码,而是为其生成了一个代理,使用代理来操作它

代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。
在某些情况下,一个客户不想或者不能直接饮用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
掌握代理模式对于Spring AOP的学习是至关重要的,甚至比Spring AOP本身的学习还要重要。


代理模式一般涉及到的角色有:
1、 抽象角色:声明真实对象和代理对象的共同接口。
2、 代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
3、 真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。

代理模式示例:我们从中介租房子。我们--中介--房东

由proxy.zip中代码可以看出,客户实际需要调用的是RealSubject类的request()方法,现在用ProxySubject来代理RealSubject类,同样达到目的,同时还封装了其他方法(preRequest(),postRequest()),可以处理一些其他问题。
另外,如果要按照上述的方法使用代理模式,那么真实角色必须是实现已经存在的,并将其作为代理对象的内部属性。但是实际使用时,一个真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀;此外,如果事先并不知道真实角色,该如何使用代理呢?这个问题可以通过Java的动态代理类来解决。


示例如附件proxy.zip:



动态代理模式(spring框架采用的模式)的例子如附件proxy2.zip:
【这个比较复杂】

以下讲解动态代理:
Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类:
1、 Interface InvocationHandler:该接口中仅定义了一个方法:
Public 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接口中声明过的方法)。


所谓Dynameic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组Intergace给它,然后该class就宣称它实现了这些Interface。你当然可以把该class的实例当做这些Interface中的任何一个来用。当然,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。


注意:动态代理只能动态代理接口,不能代理类。   

通过这种方式,被代理的对象(RealSubject)可以在运行时动态改变,需要控制的接口(Subject接口)可以在运行时改变,控制的方式(DynamicSubject类)也可以动态改变,从而实现了非常灵活的动态代理关系。

动态代理使用场合:
1、调试;
2、远程方法调用(RMI);
3、AOP;

动态代理的步骤(重点):
1、创建一个实现接口InvocationHandler的类,它必须实现invoke方法。
2、创建被代理的类以及接口。
3、通过Proxy的静态方法newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler  h)创建一个代理。
4、通过代理调用方法。


每一个代理实例都会有一个与之关联的InvocationHandler(调用处理器,也就是处理程序)。当我们调用一个代理实例的某一个方法的时候,方法调用就会被编码,并且被派发到它的调用处理器的invoke()方法上。

每一个代理的实例都会有一个与之关联的InvocationHandler(调用处理器),代理类(Proxy.newInstance(…)方法生成的)调用的任何方法都会由它的调用处理器来处理完成。


通过这种方式,被代理的对象(RealSubject)可以在运行时动态改变,需要控制的接口(Subject接口)可以在运行时改变,控制的方式(DynamicSubject类)也可以动态改变,从而实现了非常灵活的动态代理关系。


附件例子里面的动态代理里面的Proxy.newInstance(…)方法生成的对象s相当于静态代理里面的ProxySubject类的对象,相当于代理类对象。然后通过代理调用被代理类的真实的方法,代理本身它并不完成实际的操作,然后动态代理就会转到此代理相应的InvocationHandler里面的invoke(…)方法上去处理。


对下面的动态代理的代码包里面的一些代码做详细讲解:
ProxySubject.java文件里面的method.invoke(object, args);这一句代码是调用被被代理对象的将要执行的方法,完成了对真实对象的调用。
Client.java文件里面Subject s = (Subject) Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(), ih);这句代码里面不是像我们以前自己定义一个Class然后在里面写代码,而是在运行期间动态生成了一个CLass类,然后生成此Class类的一个对象。当这句代码下面调用s.request()的时候实际上就是把这个方法调动转移给in了,由in来接管,转而调用的是in里面的invoke()方法,由invoke方法完成实际的执行。

这个例子里面的ProxySubject类就是与在Client里面生成的代理对象s相关联的InvocationHandler(调用处理器,也就是调用处理程序),当对代理实例s调用方法时s.request(),将对方法调用进行编码并将其指派到它的调用处理程序ProxySubject里面的invoke方法上。

Subject s = (Subject) Proxy.newProxyInstance(clazz.getClassLoader(),
clazz.getInterfaces(), ih);
这句代码新建一个代理实例(先动态生成类然后再生成它的实例),一个代理对象,这里生成的这个对象既不是RealSubject,也不是ProxySubject的,它是运行期间动态生成的那个类的实例对象(从打印出来的结果看这个类的名称是$Proxy0,只是一个示例),这个类的特点是:
1、它实现了clazz.getInterfaces()【真实的对象RealSubject实现的所有接口】这些接口。
2、这个类的实例s是一个代理,当调用s.request()方法的时候不去调用某个真正的request方法,而是流程转到了InvocationHandler实现类里面的invoke方法里面,由这个方法去完成实际的执行
分享到:
评论

相关推荐

    Spring本质系列(2)AOP共3页.pdf.zip

    【描述】"Spring本质系列(2)AOP共3页.pdf.zip" 的描述简单明了,没有额外的技术细节,但可以推测文档可能是系列教程的一部分,专注于讲解Spring框架的核心特性——AOP。这个系列可能旨在逐步深入剖析Spring的工作...

    spring 重要的概念讲解

    本文将深入讲解Spring中的重要概念,包括AOP(面向切面编程)、DI(依赖注入)和IOC(控制反转)。 首先,Spring的轻量级特性体现在其核心包体积小,资源需求低,适合各种规模的应用,特别是小型设备。轻量级意味着...

    JAVA高并发高性能高可用高扩展架构视频教程

    揭开springAOP神秘面纱(动态代理) Mysql性能优化之索引优化 写实现Tomcat服务器 移动后台端框架设计 公司级框架原理解析 解密公司内部框架开发(打造属于自己的专属框架) 手写Tomca之深度解析动态资源请求原理 深度...

    jsp servlet struts hibernate spring

    【描述】: "本文深入探讨Java Web开发中常见的技术,包括JSP、Servlet、Struts、Hibernate和Spring,讲解它们的工作原理和实用技巧。" 【标签】: "jsp, servlet, struts, hibernate, spring" 【内容】: Java Web...

    离职手续-1_spring_

    2. **面向切面编程(AOP)**:Spring的AOP允许开发者定义“切面”,这些切面可以包含业务逻辑的各个方面,如日志、事务管理等。这样,核心业务代码可以更专注于其实质功能,而不需关心这些辅助任务。 3. **Spring ...

    spring事务测试

    本文将主要围绕Spring事务测试展开,讲解如何在Spring中进行事务管理和测试。 在Spring框架中,事务管理是通过声明式或编程式的方式来实现的。声明式事务管理通过配置XML或者使用注解来定义事务边界,使得开发者...

    全面分析Spring的编程式事务管理与声明式事务管理.doc

    本文将从 Spring 的事务管理入手,深入讲解编程式事务管理和声明式事务管理的实现机制和原理。通过本文的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之。 一、事务管理的重要性 事务管理对于企业应用至...

    java面试经典

    - **动态代理**:解释Java动态代理的实现,以及在AOP(面向切面编程)中的应用。 7. **IO流与NIO** - **字节流与字符流**:对比两者的差异,了解缓冲流的使用。 - **文件操作**:文件的创建、读写和删除,以及...

    JavaEE企业培训方案1.pdf

    此外,还涉及了AOP(面向切面编程)、Spring MVC、数据访问对象(DAO)和事务管理,以及Spring与Hibernate的整合。 整个培训方案以实践为导向,旨在帮助学员不仅理解理论知识,还能将这些知识应用于实际项目,提升...

    基于SSM框架的Java Web开发课程教学中的几点思考.zip

    在Java Web开发领域,SSM框架(Spring、Spring MVC、MyBatis)是常见的企业级应用开发技术栈。本教学资料“基于SSM框架的Java Web开发课程教学中的几点思考”探讨了如何有效地教授和学习这些关键技术,以及如何将...

    高级软件架构师培训讲义

    这部分可能解释了AOP的基本概念,展示了如何使用AOP框架(如Spring AOP)来解耦核心业务逻辑,实现代码的模块化和简洁性。 7. **07_软件架构通用服务.pdf**:通用服务是指在多个应用或系统中都能复用的服务组件,如...

    WEB多线程开发

    4. **Spring**:Spring框架是Java EE领域的另一个核心组件,它提供了全面的后端服务,包括依赖注入、AOP(面向切面编程)、事务管理等。Spring的线程模型很灵活,可以在不同层次(如Service层、DAO层)使用多线程。...

    《SSH与SSM架构》课程教学大纲.docx

    - 说明 Spring 对 AOP 的内置支持机制,包括切点、切面、连接点等概念。 - 解释事务传播特性,并理解 Spring 事务管理接口的作用。 - **第三部分**:Hibernate 框架 - 介绍数据持久化与 ORM 的概念。 - 概述 ...

    Java面试题

    本篇文档主要介绍了Java面试中经常出现的技术问题,重点围绕Struts、Spring和Hibernate三大框架进行了详细的讲解,以下是对文档内容的深入解析。 首先,Hibernate作为Java语言的一个对象关系映射(ORM)框架,它...

    leedcode.zip

    4. Spring框架的原理和使用,如依赖注入、AOP等。 5. 数据库操作,包括SQL查询、事务管理等。 6. 设计模式的理解和应用,如单例模式、工厂模式、装饰器模式等。 通过"leedcode.zip"中的Java代码,你可以对LeetCode...

    深入体验Java Web开发内幕-核心基础.pdf

    Spring MVC是Java Web中最流行和强大的MVC框架之一,它提供了丰富的功能,如依赖注入、AOP(面向切面编程)、数据验证等,极大地简化了开发过程。 在Java Web开发中,请求转发和重定向是两种常见的导航策略。请求...

    watch-party-server

    1. **Java Web开发**:项目的本质是一个Web应用,因此,对Java Servlet、JSP(JavaServer Pages)或现代的Spring Boot框架的理解是基础。它可能使用了HTTP协议来处理客户端请求,为用户提供动态内容。 2. **Spring...

Global site tag (gtag.js) - Google Analytics