来源:blog.csdn.net/duxd185120/article/details/109210224学习一个模块的设计主要看界面设计。通过界面设计,我们可以知道模块整体是如何实现的。具体的实现就是把这些接口组装起来进行实现,知道了模块接口设计,实现就变得很简单了。本文主要从aop的背景出发,通过思考需要哪些接口,来描述一个模块的功能设计规则。AOP的背景使用面向对象编程(OOP)有一些缺点。当需要为多个没有继承关系的对象引入相同的公共行为时,比如日志、安全检测等,我们只需要引用每个对象中的公共行为即可,以至于在程序中产生了很多重复的代码,程序也不容易维护,于是就有了面向对象编程的补充,即面向切面编程(AOP)。AOP的方向是水平方向,不同于OOP的垂直方向。什么是AOP,什么是面向切面编程,3个过程:找到横切点:首要目标是确定在程序中的什么地方执行横切逻辑Crosscuttinglogic(业务代码):横切逻辑代码,这个就是横切业务代码,Aop-independentweaving:将横切逻辑编织成横切点开发者主要关心的是横切逻辑的编写,只需要少量的代码编写就可以确定哪些是横切点,而无需在创建的切点上加入横切逻辑,否则就是面向对象编程。既然是水平编程,那我们程序中哪些可以作为水平切入点呢?看示例代码:publicclassTest{publicstaticvoidmain(String[]args){//@1Bb=newB();//@2b.method();//@3B.say();}staticclassB{//字段//@4私有字符串名称;//构造方法publicB(){//@1.1}//对象方法publicvoidmethod(){//@2.2}//StaticMethodstaticvoidsay(){//@3.3}}}所以我们可以分横切点分为两类:领域和方法。方法的种类很多,横切点的地方也很多。从代码来看,有以下几个地方:使用constructor创建对象constructorexecuteobjectmethodcallobjectmethodexecutestaticmethodcallstaticmethodexecutereflectionreadWriteobjectfield目标1:找到横切点那么如何定义一个横切点呢?如何用一个接口来描述一个横切点?在Java中,一切都是对象。在Java中,一个类有两个方面:字段、方法(构造函数、对象方法、静态方法),AccessibleObject在java中用于抽象公共行为。方法:是一个可以执行的程序,一段代码。因此,在横切点界面中,第一个功能就是将当前的横切点返回给用户。有两种情况:如果横切点作用于一个对象(对象字段、对象方法、构造函数),不仅需要返回AccessibleObject,还需要返回当前对象,因为通过反射调用对象方法需要通过在当前对象中。如果横切点在一个类上,就返回一个AccessibleObject。另外一个接口函数是考虑是否在横切点控制多个横切逻辑的调用。这可以由框架支持或由横切点控制。这对应责任链模型的API设计。比如tomcat中的Filter链调用就是以集合的形式调用;netty中的Handler组织是链表的形式。如果以集合的形式调用,需要在横切点的接口中定义一个方法来链式调用。(aop联盟的JoinPoint是以集合的形式调用的)然后AOP联盟使用JointPoint接口来定义横切点。publicinterfaceJoinpoint{Objectproceed()throwsThrowable;对象getThis();AccessibleObjectgetStaticPart();}Objectproceed()throwsThrowable:链式调用横切点ObjectgetThis();返回连接点的当前对象。如果当前连接点是静态的,比如静态方法,方法返回null,因为反射不需要对象,而静态方法是通过类调用的,根本没有对象,所以返回null。springaop不支持拦截静态方法,所以spring这里返回的是目标对象(代理对象)AccessibleObjectgetStaticPart();返回连接点的静态部分。对于连接点是一个方法,方法对象被返回。现在连接点的设计已经比较清晰了,接下来是连接点的扩展,比如可执行程序的子接口(构造方法,Method),字段的子接口(aop联盟做的)没有定义,只有方法级别)。AOP联盟对连接点接口的设计:比如在MethodInvocation中,返回的是Method。目标2:横切逻辑(增强)抽象增强抽象的定义实际上需要连接点信息。毕竟,增强需要在一个地方投入,因此需要连接点信息。aop联盟中的接口定义:Advice作为标记标识,拦截器作为aop联盟中的增强命名。这里可以完全去掉Interceptor,直接定义一个MethodAdvice。之所以定义为Interceptor,是因为拦截器的命名更符合编程的命名规范,让人从命名上就可以知道接口的功能。在MethodInterceptor中传入连接点信息(因为是方法拦截,所以这里是方法级别的连接点接口定义)Objectinvoke(MethodInvocationinvocation)throwsThrowable;目标三:编织首先是如何编织。编织由两种方案组成。静态编织:使用自定义类加载器机制。自定义类加载器在加载class文件的过程中,根据编织规则手动将横切逻辑编织到class文件中,然后将修改后的class文件交给JVM运行。动态编织:有很多选择,动态代理(JDKProxy),动态字节码生成技术(cglib)spring采用动态编织。动态编织就是生成一个代理对象,这个代理对象维护着当前连接点的所有拦截器,然后当目标方法被调用时,被代理类拦截,在代理类中执行aop函数。下面是一个完整的流程图:SpringAOP的实现是基于AOP联盟接口标准的设计和实现。看看aopalliance的接口和接口的API设计。上面我们已经分析过了。AOP联盟里面接口很少:近期热点文章推荐:1.1,000+Java面试题及答案(2022最新版)2.厉害了!Java协程来了。..3.SpringBoot2.x教程,太全面了!4.不要用爆破爆满画面,试试装饰者模式,这才是优雅的方式!!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!
