摘要:说明我们创建时传入了一个对象。在这个对象里我们调用了被代理的那个对象的方法,并且在其前后附加了方法。切面在指定的连接点被织入到目标对象中。因为采用动态代理,所以是在运行期完成织入。中的代理一个类被织入增强后,就产生一个结果代理类
说明:图片是我其它地方博客里的
package dproxy; /** *抽象主题 **/ interface Subject { void subjectMethod(int a,int b); } /** *具体主题 **/ /** *实现了Subject接口,并且覆盖了subjectMethod方法 **/ package dproxy; public class RealSubject implements Subject { //Joinpoint连接点 @Override public void subjectMethod(int a, int b) { // TODO Auto-generated method stub System.out.println(a+"+"+b +"="+(a+b)); } } /** *代理处理 **/ package dproxy; import java.lang.reflect.InvocationHandler; //Aspect(方面)??? public class ProxyHandler implements InvocationHandler { private Object subject; public ProxyHandler(Object subject) { // TODO Auto-generated constructor stub this.subject = subject; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); // TODO Auto-generated method stub System.out.println("调用真实主题的方法"); /** *用反射机制调用了realMethod方法 **/ method.invoke(subject, args); after(); return null; } //Advice(通知) public void before() { System.out.println("代理前的处理操作"); } //Advice(通知) public void after() { System.out.println("代理后的处理操作"); } }
invoke方法参数说明: invoke方法的第一个参数是 proxy 是 Proxy.newProxyInstance 创建的对象,我在网上看到很多文章说这个参数是被代理类的对象即RealSubject的对象,这种说法是错误的,大家可以用RTTI对proxy进行了解,它确实是 Proxy.newProxyInstance 创建的对象
构造器说明: ProxyHandler() 构造器接受一个参数,这个参数是被代理类即RealSubject的对象。
invoke内部解析: 我们在 invoke 函数里面 通过 method.invoke(subject, args); 调用了真实主题,即被代理对象的某一个方法,注意 invoke的第二个参数是 method 它指明调用被代理对象的哪一个方法,第三个参数是该方法的参数。
package dproxy; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { // TODO Auto-generated method stub /** *创建真实主题 **/ Subject realSubject = new RealSubject(); /** *创建代理处理器 **/ ProxyHandler handler = new ProxyHandler(realSubject); /** *创建代理对象 **/ Subject proxy = (Subject) Proxy.newProxyInstance(realSubject.getClass() .getClassLoader(), realSubject.getClass().getInterfaces(), handler); /** *调用动态创建的代理对象的动态生成的subjectMethod方法 **/ proxy.subjectMethod(3, 5); //执行了3+5操作 并在该操作前后调用了附加方法 } }
说明1:Proxy.newProxyInstance创建了一个代理对象,并且以Subject的身份去调用一个貌似和Subject类一模一样的接口subjectMethod由于 proxy对象是Subject类型的 即 Subject proxy ,所以我们执行 proxy.subjectMethod(3, 5);时感觉不到在用代理。
说明2:我们创建proxy时传入了一个handler对象。在这个对象里我们调用了被代理的那个对象的方法,并且在其前后附加了方法。
执行流程:
1 在Client 创建了一个被代理的对象 realSubject
2 创建了一个代理处理器,这里是代理处理器,并不是代理类,因为它不是Subject类型,也没有和Subject内部长的一样的函数所以它不是代理对象,但是它对真实对象,即realSubject 对象的调用时由这个对象代替代理类来做的。也就是代理类将对被代理对象的调用的职责委托给了这个代理处理器
3 Proxy 类创建了一个对象,然后这个类通过 java反射机制 将创建的这个对象变的类型变成了Subject,创建的这个对象内部有一个代理处理器对象handler
4 由3创建的那个代理对象,执行proxy.subjectMethod(3, 5);以Subject的身份调用了一个和Subject接口中的某个函数长的一样的一个函数,这是因为proxy是Subject类型的一个对象
5 proxy在subjectMethod函数内部将对被代理对象的调用委托给了代理处理器对象handler
和spring AOP 的关系
AOP 中的 Advice通知 就是我们在被代理方法执行前后附加的方法
AOP 中的 Joinpoint连接点 就是我们需要执行的那个 3+5的方法
AOP 中的 Aspect方面 如果我们将所有的 Advice通知 提取出来放在 一个类中就构成 了 Aspect方面
AOP 中的 Pointcut切入点 是所有符合相同规则的连接点的集合,例如所有以do开头的方法,切入点内包含一套规则用来说明该切入点包含哪些链接点
AOP 中的Introduction(引介) 引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field
AOP 中的Target(目标对象) 代理的目标对象(要增强的类)
AOP 中的织入 Weaving把切面应用到目标对象并创建新的代理对象的过程。切面在指定的连接点被织入到目标对象中。织入可以在对象生命周期的编译期、类加载期、运行期完成。Spring AOP 因为采用动态代理,所以是在 运行期 完成织入。
AOP 中的Proxy(代理) 一个类被AOP织入增强后,就产生一个结果代理类
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/65125.html
摘要:是一种特殊的增强切面切面由切点和增强通知组成,它既包括了横切逻辑的定义也包括了连接点的定义。实际上,一个的实现被拆分到多个类中在中声明切面我们知道注解很方便,但是,要想使用注解的方式使用就必须要有源码因为我们要 前言 只有光头才能变强 上一篇已经讲解了Spring IOC知识点一网打尽!,这篇主要是讲解Spring的AOP模块~ 之前我已经写过一篇关于AOP的文章了,那篇把比较重要的知...
摘要:,,面向切面编程。,切点,切面匹配连接点的点,一般与切点表达式相关,就是切面如何切点。例子中,注解就是切点表达式,匹配对应的连接点,通知,指在切面的某个特定的连接点上执行的动作。,织入,将作用在的过程。因为源码都是英文写的。 之前《零基础带你看Spring源码——IOC控制反转》详细讲了Spring容器的初始化和加载的原理,后面《你真的完全了解Java动态代理吗?看这篇就够了》介绍了下...
摘要:入门和学习笔记概述框架的核心有两个容器作为超级大工厂,负责管理创建所有的对象,这些对象被称为。中的一些术语切面切面组织多个,放在切面中定义。 Spring入门IOC和AOP学习笔记 概述 Spring框架的核心有两个: Spring容器作为超级大工厂,负责管理、创建所有的Java对象,这些Java对象被称为Bean。 Spring容器管理容器中Bean之间的依赖关系,使用一种叫做依赖...
摘要:总结动态代理的相关原理已经讲解完毕,接下来让我们回答以下几个思考题。 【干货点】 此处是【好好面试】系列文的第12篇文章。文章目标主要是通过原理剖析的方式解答Aop动态代理的面试热点问题,通过一步步提出问题和了解原理的方式,我们可以记得更深更牢,进而解决被面试官卡住喉咙的情况。问题如下 SpringBoot默认代理类型是什么 为什么不用静态代理 JDK动态代理原理 CGLIB动态代理...
摘要:使用与的静态代理不同,使用的动态代理,所谓的动态代理就是说框架不会去修改字节码,而是在内存中临时为方法生成一个对象,这个对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。 AOP(Aspect Orient Programming),我们一般称为面向方面(切面)编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理、日志、缓存...
摘要:又是什么其实就是一种实现动态代理的技术,利用了开源包,先将代理对象类的文件加载进来,之后通过修改其字节码并且生成子类。 在实际研发中,Spring是我们经常会使用的框架,毕竟它们太火了,也因此Spring相关的知识点也是面试必问点,今天我们就大话Aop。特地在周末推文,因为该篇文章阅读起来还是比较轻松诙谐的,当然了,更主要的是周末的我也在充电学习,希望有追求的朋友们也尽量不要放过周末时...
阅读 604·2023-04-26 01:53
阅读 2714·2021-11-17 17:00
阅读 2857·2021-09-04 16:40
阅读 1959·2021-09-02 15:41
阅读 795·2019-08-26 11:34
阅读 1206·2019-08-26 10:16
阅读 1297·2019-08-23 17:51
阅读 781·2019-08-23 16:50