优惠券网站开发,谷歌seo搜索引擎下载,wordpress配置数据库主机名,wordpress图片视频主题文章目录 1、语法2、通配符3、execution4、within5、annotation6、args7、args8、bean9、this10、target11、target12、within13、表达式组合14、补充 1、语法
动作关键词(访问修饰符 返回值 包名.类/接口名 .方法名(参数)异常名)
举例#xff1a;
execution(public User c… 文章目录 1、语法2、通配符3、execution4、within5、annotation6、args7、args8、bean9、this10、target11、target12、within13、表达式组合14、补充 1、语法
动作关键词(访问修饰符 返回值 包名.类/接口名 .方法名(参数)异常名)
举例
execution(public User com.llg.service.Uservice.findById(int))动作关键字描述切入点的行为动作execution即执行到指定切入点方法修饰符public、private等可以省略返回值包名类/接口名参数异常名方法定义中抛出指定异常可以省略
2、通配符
使用通配符来描述切入点提高效率
* 代表单个独立的任意符号可以独立出现也可做为前缀或后缀匹配符。
execution(public * com.llg.*.UserService.find* (*))以上代表匹配com.llg包下得任意包中得UserService类或接口中所有find开头得带有一个参数注意不是无参数、返回类型任意的public方法
. .即多个连续的任意符号可独立出现常用于简化包名与参数的书写
execution(public User com..UserService.findById(..))以上代表匹配com包下的任意包中的UserService类或接口中所有名称为findById的方法 形参个数无所谓 用于专门用于匹配子类类型
execution(* *..*Service.*(..))3、execution
最常用表达式中是一个方法。举例
匹配所有的不带参数的add()方法
execution(* add())匹配所有抛出Exception的方法
execution(* *(..) throws Exception)写个简单的完整例子
//通知类
Component
Aspect
public class CutAdvice {Pointcut(execution(* *..MyService.myExecution(..)))public void pointCut(){}Before(pointCut())public void beforeSome(){System.out.println(前置AOP成功);}
}//即将匹配到被增强的切点方法
Service
public class MyService {public void myExecution(){System.out.println(execution ...);}
}
调用下这个切点方法看到AOP增强成功 4、within
根据一个类来匹配这个类中的所有方法将被匹配为切点并被拦截增强。
匹配UserServiceImpl类对应对象的所有方法外部调用而且这个对象只能是UserServiceImpl类型不能是其子类型
within(com.llg.service.UserServiceImpl)匹配com.llg包及其子包下面所有的类的所有方法的外部调用
within(com.elim..*)写个例子展示下效果
//通知类
Component
Aspect
public class CutAdvice {Pointcut(within(cn.llg.user.service.MyService))public void pointCut(){}Before(pointCut())public void beforeSome(){System.out.println(MyService中的方法即将被调用前置AOP成功);}
}//即将匹配到的类
Service
public class MyService {public void methodOne(){System.out.println(MyService类中的methodOne方法);}public void methodTwo(){System.out.println(MyService类中的methodTwo方法);}
}调用MyService类中的两个方法看到这两个方法均被增强 5、annotation
根据注解来匹配用于匹配方法上拥有指定注解的情况
匹配所有的方法上拥有MyAnnotation注解的方法
annotation(com.llg.service.MyAnnotation)按注解匹配切点还可以通知类中获取注解的属性贴个例子
Component
Aspect
public class RedisAdvice {Pointcut(annotation(org.springframework.cache.annotation.Cacheable))public void redisCut(){}//Cacheable redisInfoAround(redisCut() annotation(redisInfo))public Object doAround(ProceedingJoinPoint proceedingJoinPoint,Cacheable redisInfo) throws Throwable {//获取属性StringBuilder redisKey new StringBuilder(redisInfo.key()).append(::).append(redisInfo.value()[0]);MethodSignature signature (MethodSignature) proceedingJoinPoint.getSignature();String methodName signature.getName();// ....Object ret proceedingJoinPoint.proceed();return ret;}}获取切点表达式注解的属性跳这篇【用AOP拦截注解并获取注解属性值】
6、args
按方法的参数匹配即增强形参符合表达式的方法。
匹配并增强任何不带参数的方法
args()匹配并增强带任意个参数的方法等于是全员增强了
args(..)匹配并增强只有一个形参且类型为String的方法
args(java.lang.String)匹配并增强形参有任意个但第一个类型为String的方法
args(java.lang.String,..)匹配并增强形参有任意个但最后一个参数为String类型的方法
args(..,java.lang.String)7、args
按参数的类型的类上的注解匹配当某方法的形参类型的类上有指定的注解则匹配成功。
args(com.sun.MyAnnotation)当有个方法method(MyParam param它形参的类型为MyParamMyParam类上有MyAnnotation注解时匹配成功增强method方法
8、bean
按bean去匹配只要是这个bean在调用的方法就做AOP增强。
匹配Spring Bean容器中id或name为myBean的bean并增强它调用的所有方法
bean(myBean)匹配所有id或name为以user开头的bean并增强它调用的所有方法
bean(user*)9、this
Spring AOP基于代理实现先看下整个流程 即Spring容器初始化Bena时发现bean对应的类中有切点时就不再创建原始对象了而是创建这个类的对象的代理对象切点表达式中的this就是指这个代理对象。
语法this(type)当生成的代理对象可以转型为type这个类型时匹配成功
this(com.service.IUserService)匹配生成的代理对象是IUserService类型的所有方法的外部调用
10、target
和this相反被代理的目标对象可以被转换为指定的类型时匹配成功。
target(com.service.IUserService)匹配被代理的目标对象能够转换为IUserService类型的所有方法的外部调用
11、target
和args、args类似当被代理的目标对象对应的类型及其父类型上拥有指定的注解时匹配成功
target(com.sun.MyAnnotation)被代理的目标对象对应的类型上拥有MyAnnotation注解时匹配成功
12、within
匹配被代理的目标对象对应的类型或其父类型拥有指定的注解的情况但只有在调用拥有指定注解的类上的方法时才匹配。
within(com.spring.service.MyAnnotation)举个例子
MyAnnotation
class A {void method a();
}B类集成A类且有做为子类特有的方法B
class B {void method b();
}此时
new A().a() 匹配
new B().b() 不匹配
new B().a() 匹配
子类B重写方法a后再调用
new B().a() 不匹配后面这几个没测过应该用到的场景不多。
13、表达式组合
上面的一个个表达式可以通过逻辑运算符或与非连接起来以实现匹配到更复杂的增强需求。
匹配id或name为userService的bean调用的方法且这个方法必须无参
bean(userService) args()匹配id或name为userService的bean调用的方法且这个方法必须至少有一个形参
bean(userService) !args()匹配id或name为userService的bean调用的方法或者使用了MyAnnotation这个注解的方法
bean(userService) || annotation(MyAnnotation)14、补充
开发中不一定要严格按下面的标准流程先定义一个无意义无返回值的切点定义类再写一个新方法来写增强的功能。
Component
Aspect
public class CutAdvice {//先定义一个无意义无返回值的切点定义类Pointcut(execution(* *..MyService.myExecution(..)))public void pointCut(){}Before(pointCut())public void beforeSome(){System.out.println(前置AOP成功);}
}直接将切点方法或者切点表达式写到五种通知类型的注解中也行
//直接写切点
Before(com.llg.service.Uservice.findById())
public void beforeSome() {System.out.println(AOP前置);
}也可直接跟切点表达式
/*** 所有的add方法执行时*/
Before(execution(* add()))
public void beforeExecution() {System.out.println(AOP前置.....);
}