简介
面向方面编程(AOP)通过提供另一种思考程序结构的方式来补充面向对象编程(OOP)。OOP中模块化的关键单元是类,而在AOP中,模块化单元是方面。方面实现了跨越多种类型和对象的关注点(例如事务管理)的模块化。(这些担忧在AOP文献中通常被称为“横切”问题。)
概念和术语
- Aspect(切面):横切关注点被模块化的特殊对象。即,它是一个类
- Join point(连接点):程序执行期间的一个点,例如执行方法或处理异常。在Spring AOP中,连接点始终表示方法执行。
- Advice(通知):切面必须要完成的工作。即,它是类中的一个方法。
- Pointcut(切点):由切入点表达式匹配的连接点(就是符合表达式的连接点的集合)
- Introduction(引入):Spring AOP允许您向任何建议的对象引入新接口(以及相应的实现),就是在给类添加接口。
- Target object(目标对象):被通知对象。
- AOP proxy(AOP代理):在ioc容器初始化时,将目标对象变成代理对象
- Weaving(织入)
通知类型
- Before advice(@Before):在连接点之前运行,但无法阻止执行流程进入连接点(除非它抛出异常)
- After returning advice (@AfterReturn):在连接点正常完成后运行(如果方法返回而不抛出异常)
- After throwing advice (@AfterThrowing):如果方法通过抛出异常退出
- After(@After):无论连接点退出的方式(正常或异常返回),都要执行建议
- Around(@Around): around通知可以在方法调用之前和之后执行自定义行为,它还负责选择是继续连接点还是通过返回自己的返回值或抛出异常来快速建议的方法执行。
* 由于Spring AOP(如AspectJ)提供了全方位的建议类型,因此我们建议您使用可以实现所需行为的最不强大的建议类型 (应该就是能用Before或者After的就尽量别用Around叭,不强大的能解决,何必要用强大的呢~,应该是这样子叭)
基本使用
启用@AspectJ支持
1 |
|
声明一个切面(里面包含切点,通知)
1 |
|
通知参数(参数也可以放在PointCut中)
- 如果第一个参数是的JoinPoint,ProceedingJoinPoint,JoinPoint.StaticPart类型,可以直接写,JoinPoint接口有许多方法:
- getTarget() getTarget():返回目标对象。
- getArgs():返回方法参数。
- getSignature():返回正在通知的方法的描述。
- toString():打印通知方法的有用说明。
- getThis():返回代理对象。
- ProceedingJoinPoint参数只能写在Around通知中
1 | ("PointCutOne() && args(test)") |
通知顺序
当多条建议都想在同一个连接点运行时会发生什么?还没去了解。哈哈哈哈哈哈
测试类
1 | public class Application { |
1 |
|
结果(around和其他的分开调试)
1 | before ....... |
引入(Introductions)
前面描述的几种增强(Advice)都是在目标方法范围内织入,而引介(Introduction)不同,直接在类级别上添加目标未实现的接口方法。
根据官方文档的介绍:您可以使用@DeclareParents注解进行介绍。此注解用于声明匹配类型具有新父级
声明一个接口,和一个实现类
1 | public interface SayHello { |
1 | public class SayHelloImpl implements SayHello { |
在切面中使用@DeclareParents注解对特定的类进行引入新方法
1 | (value = "com.yb.test.*",defaultImpl = SayHelloImpl.class) |
测试
1 | public class Application { |
结果
1 | com.yb.myinterface.SayHello |
说明这个对象确实实现了接口 (就是不知道有啥用处。。。感觉直接实现接口不是差不多嘛)
官方文档