Spring AOP 面向切面编程
AOP背景
AOP英语全称 Aspect Oriented Programming 即面向切面编程,它主要实现横切方向的编程。何为横切方向编程呢?如下图所示:左侧的就是我们平时编程习惯,将所有的功能串起来,而右侧则是面向切面编程,其核心内容是将与业务无关的逻辑抽象出来。其本质还是通过动态代理来实现,来增强目标类的功能。
AOP技术相关概念
- Aspect(切面): 切入点和通知点一起构成了切面
- Pointcut(切入点):本质上是一个匹配连接点的,可以理解为对连接点的正则匹配,其常见的有call(匹配调用), execution(匹配执行), get(get方法), set(setf方法), preinitialization(预初始化), initialization(初始化), staticinitialization(静态初始化), handler(异常处理类), adviceexecution(通知执行)
- Join Point(连接点):是程序执行中的一个精确执行点,例如类中的一个方法等,其中常用的AspectJ支持11种连接点: method call(方法调用), method execution(方法执行), constructor call(构造函数调用), constructor execution(构造函数执行), field get(属性get方法), field set(属性set方法), pre-initialization(预初始化), initialization(初始化), static initialization(静态初始化), handler(异常处理), advice execution(通知执行)
- Advice(通知):用于执行增强的具体业务逻辑,可以将其理解为代理类的增强逻辑
Spring AOP实践
1、 为了让spring支持基于注解进行开发AOP,首先添加如下支持
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}
2、 声明一个切面类
import org.aspectj.lang.annotation.Aspect;
@Aspect
@Component //**注意此处一定要加上,不然不会生效,因为@Aspect不是spring的自带注解,其不会将其当做bean处理**
public class NotVeryUsefulAspect {
}
3、 声明一个切入点
@Pointcut("execution(* transfer(..))") // the pointcut expression
private void anyOldTransfer() {} // the pointcut signature
4、 声明通知类型
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
@Component //注意此处一定要加上,不然不会生效,因为@Aspect不是spring的自带注解,其不会将其当做bean处理
public class BeforeExample {
@Before("com.xyz.myapp.CommonPointcuts.anyOldTransfer()")//注意和PointCut的类保持一致
public void doAccessCheck() {
// ...
}
}
如果切点仅在一处使用,我们可以将PointCut和Advice合在一起,如下所示:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
@Component //注意此处一定要加上,不然不会生效,因为@Aspect不是spring的自带注解,其不会将其当做bean处理
public class BeforeExample {
@Before("execution(* transfer(..))")//注意和PointCut的类保持一致
public void doAccessCheck() {
// ...
}
}