'''
博主最近有些郁闷,郁闷啥呢,就是java里的aop,这玩意在项目里经常看到老司机使用,但具体怎
么用起来的,就懵逼了;或许是实在受不了,决定写下此篇博文,将博主的小小见解同大家一起讨论下。本
文将通过以下几点,说说我所认识的aop:
'''
我们知道Spring提供了两个核心功能,一个是IoC(控制反转),另外一个便是Aop(面向切面编程),IoC有助于应用对象之间的解耦,AOP则可以实现横切关注点(如日志、安全、缓存和事务管理)与他们所影响的对象之间的解耦。AOP称为面向切面编程,能够让我们在不影响原有功能的情况下,对程序进行横向扩展;在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,据说Struts2的拦截器设计就是基于AOP的思想,没去了解过,我也不关心。哈哈,要我说,这玩意就是能够监听一些共性的地方,在程序执行的生命周期某个时间点执行指定的钩子函数。
什么叫横向扩展:“横向”说白了就是程序执行时的某个节点,要处理的步骤变多了,"扩展"也就是说这段程序的功能变多了。如果现有某个类的某个方法是已经封装好的,现在我们需要在执行这个方法的时候加点自己的东西,对原方法的执行进行干预。当然要求是不能破坏原类。这时需要AOP思想,把这个方法,即切点扩展成一个面来进行操作。(生成该类的代理,对代理进行操作)。
(1)Aspect(切面):通常是一个类,里面可以定义切入点和通知
(2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用
(3)Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around
(4)Pointcut(切入点):就是带有通知(意味着会被执行、走到)的连接点,在程序中主要体现为书写切入点表达式
切入点和连接点的理解:说白了,条条大路通罗马,最终你只会走一条路,那么这条路上所有的驿站、车站就是连接点。但是其他路上的驿站、车站也是切入点,只是你不走而已。也就是说,切入点是编译时确定的点,连接点是运行时具体行走确定的点。无论是切入点还是连接点,它们都可以插入被执行的切面代码。切入点和连接点都是定义了切面将可能于何处被执行的含义。我们来看下切入点如何应用到实际的切面类中:(图片来自网络)
切入点表达式:切入点表达式的定义算是整个AOP中的核心,有一套自己的规范
A:@Pointcut("execution(* com.aijava.springcode.service..*.*(..))") execution:用来匹配执行方法的连接点
第一个*表示匹配任意的方法返回值,..(两个点)表示零个或多个,上面的第一个..表示service包及其子包,第二个*表示所有类,第三个*表示所有方法,第二个..表示方法的任意参数个数
B:@Pointcut("within(com.aijava.springcode.service.*)")
within限定匹配方法的连接点,上面的就是表示匹配service包下的任意连接点
C:@Pointcut("this(com.aijava.springcode.service.UserService)")
this用来限定AOP代理必须是指定类型的实例,如上,指定了一个特定的实例,就是UserService
D:@Pointcut("bean(userService)") bean也是非常常用的,bean可以指定IOC容器中的bean的名称
通知的理解:通知定义了切面要干什么、要执行什么代码,以及它将于何时被调用。而切入点定义了切面代码将于何处被执行,可以想到,通知和切入点是搭配使用的,即“通知切入点将于何时执行"通知"这段代码”。
通知类型细说:通知也是有优先级、顺序的,虽然从下面的描述大致可以猜出来执行优先级,但这里还是描述下。进入目标方法时,先织入Around,再织入Before,退出目标方法时,先织入Around,再织入AfterReturning,最后才织入After。注意:Spring AOP的环绕通知会影响到AfterThrowing通知的运行,不要同时使用!同时使用也没啥意义。
(1)Before:在目标方法被调用之前做增强处理,@Before只需要指定切入点表达式即可
(2)AfterReturning:在目标方法正常完成后做增强,@AfterReturning除了指定切入点表达式后,还可以指定一个返回值形参名returning,代表目标方法的返回值
(3)AfterThrowing:主要用来处理程序中未处理的异常,@AfterThrowing除了指定切入点表达式后,还可以指定一个throwing的返回值形参名,可以通过该形参名
来访问目标方法中所抛出的异常对象
(4)After:在目标方法完成之后做增强,无论目标方法时候成功完成。@After可以指定一个切入点表达式
(5)Around:环绕通知,在目标方法完成前后做增强处理,环绕通知是最重要的通知类型,像事务,日志等都是环绕通知,注意编程中核心是一个ProceedingJoinPoint