Spring 基于注解使用 AOP
概念
面向切面编程。将多个对象的公共行为抽取封装成一个可重用的模块。降低了模块之间的耦合度。同时提高了系统的可维护性。一般用于权限认证,日志等。
AOP 是基于动态代理实现的。如果要代理的对象实现了某个接口,那么 AOP 就会使用 JDK 动态代理创建对象。而没有实现接口的对象,就无法使用 JDK 动态代理。使用 Cglib 动态代理生成一个被代理的子类来作为代理。
Aspect
(切面): 切点 + 通知。在什么时候,什么地方,做的什么增强
Joint point
(连接点):使用通知的一个时机,一般是方法的调用,或异常被抛出
Pointcut
(切点):通过通配、正则表达式等方式,定义了切面发生在哪里
Advice
(通知):告诉切面要做什么,什么时候开始,比如 Before、After、Around 等等
Target
(目标对象):被通知的对象
Weaving
(织入):把切面应用到目标对象,创建对象的一个过程。可以在编译时或运行时完成织入操作。
Spring AOP 和 AspectJ AOP 的选择
Spring AOP 属于运行时增强。AspectJ 是编译时增强,Eclipse 基金会出品。SpringAOP 基于代理,而 AspectJ 是基于字节码操作。因为基于字节码操作,所以性能上,AspectJ 比 springAOP 要好上一点。切面越多效果越明显
几种通知
- @Before:前置通知
- @AfterRetunring:后置通知
- @Around:环绕通知
- @AfterThrowing:异常通知
- @After:最终通知
为什么选择注解的方式开发 AOP
先来看一下不使用注解的方式:
execution (<修饰符模式>?< 返回类型模式 >< 方法名模式 >(< 参数模式 >)< 异常模式 >?) 这是连接点的基本语法
execution (* com.sora33.aop.service.sora33Service.sora33ServiceImpl.*(..)) 这个表示切到 sora33ServiceImpl 下的所有方法
再来看一下注解的方式:
@Around (“@annotation (com.sora33.aop.MethodAspect)”) 只需要表明我们注解所在位置。然后就会自动匹配有这个注解的方法
实战
先引入 aspectjweaver 依赖
1 | <!--aspect--> |
声明一个接口
1 | /** |
写一个测试方法,加上我们刚刚声明的注解,表示这个方法需要被切入
1 |
|
然后写一个 Aspect 类,定义 AOP 的业务逻辑
1 |
|
执行伪代码如下👇:
1 | 类名:TestController |