AOP

一、AOP简介

1.什么是AOP?

        Aspect Oriented Programmig(面向切面编程),是一种指导如何组织程序结构的编程思想。

2.作用

        在不改变源代码的基础上进行功能增强

3.几个概念

(1)连接点(JoinPoint)

        程序执行过程中的任意位置,可以是执行方法、抛出异常、设置变量等。在Spring中,可以将连接点理解为某个方法的执行

(2)切入点(Pointcut)

        是匹配连接点的式子,在SpringAop中,一个切入点可以只描述一个具体方法,也可以匹配多个方法。

(3)通知(Advice)

        在切入点执行的操作(共性功能),在Spring中这个操作最终以方法的形式呈现。
【tips】通知类:定义通知的类。

(4)切面(Aspect)

        描述通知与切入点的对应关系,不然多个通知不知该对应哪个切入点了。

二、AOP的使用(使用注解开发AOP)

1.导坐标

(1)spring-aop(随spring-context已自动导入)
(2)aspectjweaver

2.定义连接点方法(即原始操作)

        

3.创建共性功能(通知类与通知)

(1)在SpringConfig配置类中声明使用注解开发AOP(@EnableAspectJ***)

        

(2)定义通知类,将其定义为Bean(@Component),并声明该类为切面类(@Aspect)

(3)定义通知(即方法)

        

4.定义切入点(★)

(1)定义一个私有“空”方法

        切入点的定义依托一个无实际意义的“三无”私有方法,即无参数、无返回值、方法体无逻辑

(2)定义切入点(@Pointcut)

        切入点是一个位置,即运行到哪里需要加功能(即通知)。
           

5.绑定通知与切入点的对应关系(@Before)

        

三、AOP的工作流程

1.Spring容器启动

2.读取切入点

        读取所有切面配置中的切入点,即与切面绑定的切入点,没绑定的不读取
        

3.初始化Bean,判断切入点是否被匹配

        初始化Bean,判断Bean对应的类中的方法是否能匹配到切入点:
(1)匹配失败:创建Bean对象,继续4.(1);
(2)匹配成功:创建原始对象(目标对象)的代理对象,继续4.(2)。
【tips】SpringAOP的本质:整个AOP的实现就是通过代理模式来实现的。

4.获取Bean,执行方法

(1)获取Bean,调用方法并执行,完成操作;
(2)获取的Bean是代理对象,根据代理对象的运行模式运行原始方法与增强的内容,完成操作。
【tips】①目标对象(Target):使用AOP时,最终是代理对象在运行,被这个代理对象所代理的原始对象,称为目标对象。
             ②代理(Proxy):目标对象无法直接完成工作,需要对其进行功能回填,通过原始对象的代理对象来实现。

四、AOP切入点表达式

1.语法格式

        切入点表达式标准格式:动作关键字(访问修饰符  返回值类型  包名.类/接口名.方法名(参数)异常名)
        
(1)动作关键字:描述切入点的动作行为,如execution表示执行到指定切入点
(2)访问修饰符:public,private等,可忽略
(3)异常名:方法定义中抛出指定异常,可忽略

2.通配符★

(1)*:单个独立的任意符号,可单独出现,也可以作为前缀或后缀的匹配符出现
        
(2)..:多个连续的任意符号,常用于简化包名和参数的书写
        
(3)+:专用于匹配子类类型

3.书写技巧

(1)描述切入点通常描述接口,而不描述其实现类;
(2)包名描述尽量不使用..匹配,效率过低,常用*做单个包描述匹配或精准匹配
(3)接口名/类名书写名称与模块相关的采用*匹配,如UserService描述成*Service;
(4)方法名书写动词采用精准匹配,如selectAll就写成selectAll;名词采用*匹配,如getById写成getBy*。

五、AOP通知类型

        AOP通知描述了抽取的共性功能,根据共性功能抽取的位置不同,最终运行代码时要将其加入到响应的位置。

1.前置通知@Before

2.后置通知@After

3.环绕通知★@Around

        需要有一个对原始操作的调用来区分前后:
        
【注意事项】
        

4.返回后通知@AfterReturning

5.抛出异常后通知@AfterThrowing

六、ProceedingJoinPoint的使用

1.获取执行签名信息

Signature signature = pjp.getSignature();

2.通过签名获取执行类型(接口名)

String className = signature.getDeclaringTypeName();

3.通过签名获取执行操作名(方法名)

String methodName = signature.getName();
【输出结果】:
System.out.println(className+"业务层接口"+methodName+"万次执行时间:" + (end - start) + "ms");
//com.service.AccountService业务层接口findAll万次执行时间:2053ms

七、AOP通知获取原始操作的数据

1.获取原始操作的参数

(1)@Before和@After获取参数

        用JoinPoint的getArgs方法。JoinPoint对象描述了连接点方法的运行状态,可以获取原始方法的调用参数。
        

(2)@Around获取参数

        用ProceedingJoinPoint(是JoinPoint的子类)的getArgs方法。
        

2.获取原始操作的返回值

        只有@Around和@AfterReturning能获取返回值。

(1)@Around获取返回值

        

(2)@AfterReturning获取返回值

        先定义一个用来接收返回值的形参,并在@AfterReturning中用returing属性声明接收返回值的形参
        

3.获取原始操作的异常

        只有@Around和@AfterThrowing能获取返回值。

(1)@Around获取异常

        直接try...catch...
        

(2)@AfterThrowing获取异常

        先定义一个用来接收异常的形参,并在@AfterThrowing用throwing属性声明接收异常的形参
        

全部评论

相关推荐

牛客101244697号:这个衣服和发型不去投偶像练习生?
点赞 评论 收藏
分享
牛客963010790号:为什么还要收藏
点赞 评论 收藏
分享
1 4 评论
分享
牛客网
牛客企业服务