-
应用场景:
权限控制、 缓存控制、事物控制、 审计日志、性能监控、分布式日子、异常处理 -
pointcut
- 通配符:*(匹配任意数量的字符)、+(匹配制定类及其子类)、…(一般用于匹配任意数的子包或者参数)
- 逻辑运算符: && 、|| 、!
- designators(指示符):
匹配方法: execution()
匹配注解: @target() 、@args()、@within()、@annotation()
匹配包或者类型:within()
匹配对象: this()、bean()、target()
匹配参数: args()
// >>>>>>>>>>>>>>>> 匹配包及其子包<<<<<<<<<<<<<<<<<<<
//匹配ProductService类里的所有方法
@Pointcut("within(com.imooc.service.ProductService)")
public void matchType(){}
//匹配com.imooc包及子包下所有类的方法
@Pointcut("within(com.imooc..*)")
public void matchPackage(){}
// >>>>>>>>>>>>>>>>> 匹配对象 <<<<<<<<<<<<<<<<<<<<<<<
//匹配AOP对象的目标对象为指定类型的方法,即DemoDao的aop代理对象的方法
@Pointcut("this(com.imooc.DemoDao)")
pblic void thisDemo(){}
//匹配实现IDao接口的目标对象(而不是aop代理后的对象)的方法,这里即DemoDao的方法
@Pointcut("target(com.imooc.IDao)")
public void targetDemo(){}
/**
* target和this的区别:
* Introduction:动态生成方法
* target无法拦截introduction动态生成的方法,而this可以
*/
//匹配所有以Service结尾的bean里头的方法
@Pointcut("bean(*Service)")
public void beanDemo(){}
// >>>>>>>>>>>>>>>>>> 参数匹配 <<<<<<<<<<<<<<<<<<<
//匹配任何以find开头而且只有一个Long参数的方法
@Pointcut("execution(* *..find*(Long))"){}
public void demo1(){}
//匹配任何只有一个Long参数的为Long型的方法
@Point cut("args(Long)")
public void demo2(){}
//匹配任何以find开头的而且第一个参数为Long型的方法
@Pointcut("execution(* *..find*(Long,..))")
public void demo3(){}
//匹配第一个参数为Long型的方法
@Pointcut("args(Long,..)")
public void demo4(){}
// >>>>>>>>>>>>>>>>>>>>>> 匹配注解 <<<<<<<<<<<<<<<<<<<<<<<<
//匹配方法标注有AdminOnly的注解的方法,匹配方法级别注解
@Pointcut("@annotation(com.imooc.demo.security.AdminOnly)")
public void annoDemo(){}
//匹配标注有Beta的类中的所有方法,要求的annotation的RetentionPolicy级别为CLASS, 匹配类级别注解
@Pointcut("@within(com.google.common.annotations.Beta)")
public void annoWithinDemo(){}
//匹配标注有Repository的类中的方法,要求的annotation的RetentionPolicy级别为RUNTIME,匹配类级别注解
@Pointcut("@target(org.springframework.stereotype.Repository)")
public void annoTargetDemo(){}
/**
*target和within在spring环境中是一样的
*/
//匹配传入的参数类标注有Repository注解的方法,匹配参数级别注解
@Pointcut("@args(org.springframework.stereotype.Repository)")
public void annoArgsDemo(){}
execution(修饰符? 返回值类型 类型声明?方法名(参数列表) 异常列表? ) “?” 表示可选的
- 5种Advice注解
@Before:前置通知
@After(finally):后置通知,方法执行完之后,无论是否throws,都会执行
@AfterReturning:返回通知,成功执行之后,只拦截有返回值的
@AfterThrowing:异常通知,抛出异常之后,只拦截有异常抛出的
@Around:环绕通知
-
注意:
aop 是通过动态代理目标对象的方式实现切面编程,方法的真正执行还是调用目标对象来执行方法,因此无法拦截方法中的方法,即无法拦截内部方法。因为内部方法的执行是通过目标对象直接执行的,而不是通过动态代理的方式执行的。