一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第21天,点击查看活动详情。
AOP核心概念
- Joinpoint(连接点):所谓连接点是指那些可以被增强到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点
- Pointcut(切入点):所谓切入点是指被增强的连接点(方法)
- Advice(通知/ 增强):所谓通知是指具体增强的代码
- Target(目标对象):被增强的对象就是目标对象
- Aspect(切面):是切入点和通知(引介)的结合
- Proxy (代理):一个类被 AOP 增强后,就产生一个结果代理类
切点确定
切点表达式
可以使用切点表达式来表示要对哪些方法进行增强。
写法:execution([修饰符] 返回值类型 包名.类名.方法名(参数))
- 访问修饰符可以省略,大部分情况下省略
- 返回值类型、包名、类名、方法名可以使用星号* 代表任意
- 包名与类名之间一个点 . 代表当前包下的类,两个点 .. 表示当前包及其子包下的类
- 参数列表可以使用两个点 .. 表示任意个数,任意类型的参数列表
例如:
execution(* com.springstudy.service.*.*(..)) 表示com.springstudy.service包下任意类,方法名任意,参数列表任意,返回值类型任意
execution(* com.springstudy.service..*.*(..)) 表示com.springstudy.service包及其子包下任意类,方法名任意,参数列表任意,返回值类型任意
execution(* com.springstudy.service.*.*()) 表示com.springstudy.service包下任意类,方法名任意,要求方法不能有参数,返回值类型任意
execution(* com.springstudy.service.*.delete*(..)) 表示com.springstudy.service包下任意类,要求方法不能有参数,返回值类型任意,方法名要求已delete开头
@Pointcut("execution(* com.springstudy.service..*.*(..))")
public void pt(){
}
切点函数@annotation
我们也可以在要增强的方法上加上注解。然后使用@annotation来表示对加了什么注解的方法进行增强。
写法: @annotation(注解的全类名)
例如:
自定义注解如下
自定义注解需要加上元注解
@Target({ElementType.METHOD})//该注解可以加在方法上 @Retention(RetentionPolicy.RUNTIME)这两个就是元注解
@Target({ElementType.METHOD})//该注解可以加在方法上
@Retention(RetentionPolicy.RUNTIME)
public @interface InvokeLog {
}
给需要增强的方法增加注解
@Servicepublic class PhoneService {
@InvokeLog
public void deleteAll(){
System.out.println("PhoneService中deleteAll的核心代码");
}}
切面类中使用@annotation来确定要增强的方法
@Component
@Aspect
public class MyAspect {
// 用Pointcut注解中的属性来指定对哪些方法进行增强
@Pointcut("@annotation(com.springstudy.aspect.InvokeLog)")
public void pt(){}
/*
用@Before注解来指定该方法中是增强的代码,并且是在被增强方法执行前执行的
@Before的属性写上加了@Pointcut注解的方法: 方法名()
*/
@Before("pt()")
public void methodbefore(){
System.out.println("方法被调用了");
}
}