spring aop中pointcut表达式完整版
spring aop中pointcut表达式完整版
本文主要介绍spring aop中9种切入点表达式的写法
- execute
- within
- this
- target
- args
- @target
- @within
- @annotation
- @args
0. 示例代码git地址
https://gitee.com/likun_557/spring-aop-demo
1.execute表达式
拦截任意公共方法
execution(public * *(..))
拦截以set开头的任意方法
execution(* set*(..))
拦截类或者接口中的方法
execution(* com.xyz.service.AccountService.*(..))
拦截AccountService(类、接口)中定义的所有方法
拦截包中定义的方法,不包含子包中的方法
execution(* com.xyz.service.*.*(..))
拦截com.xyz.service包中所有类中任意方法,不包含子包中的类
拦截包或者子包中定义的方法
execution(* com.xyz.service..*.*(..))
拦截com.xyz.service包或者子包中定义的所有方法
2.within表达式
表达式格式:包名.* 或者 包名..*
拦截包中任意方法,不包含子包中的方法
within(com.xyz.service.*)
拦截service包中任意类的任意方法
拦截包或者子包中定义的方法
within(com.xyz.service..*)
拦截service包及子包中任意类的任意方法
3.this表达式
代理对象为指定的类型会被拦截
目标对象使用aop之后生成的代理对象必须是指定的类型才会被拦截,注意是目标对象被代理之后生成的代理对象和指定的类型匹配才会被拦截
this(com.xyz.service.AccountService)
示例
this表达式的使用,可能不是很好理解,用示例说明一下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ms</groupId>
<artifactId>spring-aop-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-aop-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
package com.ms.aop.jthis.demo1;
public interface IService {
void m1();
}
package com.ms.aop.jthis.demo1;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class ServiceImpl implements IService {
@Override
public void m1() {
log.info("切入点this测试!");
}
}
package com.ms.aop.jthis.demo1;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
@Slf4j
public class Interceptor1 {
@Pointcut("this(com.ms.aop.jthis.demo1.ServiceImpl)")
public void pointcut() {
}
@Around("pointcut()")
public Object invoke(ProceedingJoinPoint invocation) throws Throwable {
log.info("方法执行之前");
Object result = invocation.proceed();
log.info("方法执行完毕");
return result;
}
}
package com.ms.aop.jthis.demo1;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@ComponentScan(basePackageClasses = {Client.class})
@EnableAspectJAutoProxy
@Slf4j
public class Client {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Client.class);
IService service = annotationConfigApplicationContext.getBean(IService.class);
service.m1();
log.info("{}", service instanceof ServiceImpl);
}
}
执行结果
10:27:12.277 [main] INFO com.ms.aop.jthis.demo1.ServiceImpl - 切入点this测试!
10:27:12.277 [main] INFO com.ms.aop.jthis.demo1.Client - false
@EnableAspectJAutoProxy:表示若spring创建的对象如果实现了接口,默认使用jdk动态代理,如果没有实现接口,使用cglib创建代理对象
所以 service 是使用jdk动态代理生成的对象,service instanceof ServiceImpl 为 false
@Pointcut("this(com.ms.aop.jthis.demo1.ServiceImpl)")表示被spring代理之后生成的对象必须为com.ms.aop.jthis.demo1.ServiceImpl才会被拦截,但是service不是ServiceImpl类型的对象了,所以不会被拦截
修改代码
@EnableAspectJAutoProxy(proxyTargetClass = true)
proxyTargetClass=true表示使用cglib来生成代理对象
执行结果:
10:34:50.736 [main] INFO com.ms.aop.jthis.demo1.Interceptor1 - 方法执行之前
10:34:50.755 [main] INFO com.ms.aop.jthis.demo1.ServiceImpl - 切入点this测试!
10:34:50.756 [main] INFO com.ms.aop.jthis.demo1.Interceptor1 - 方法执行完毕
10:34:50.756 [main] INFO com.ms.aop.jthis.demo1.Client - true
service 为 ServiceImpl类型的对象,所以会被拦截
4.target表达式
目标对象为指定的类型被拦截
target(com.xyz.service.AccountService)
目标对象为AccountService类型的会被代理
示例
package com.ms.aop.target;
public interface IService {
void m1();
}
package com.ms.aop.target;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class ServiceImpl implements IService {
@Override
public void m1() {
log.info("切入点target测试!");
}
}
package com.ms.aop.target;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
@Slf4j
public class Interceptor1 {
@Pointcut("target(com.ms.aop.target.ServiceImpl)")
public void pointcut() {
}
@Around("pointcut()")
public Object invoke(ProceedingJoinPoint invocation) throws Throwable {
log.info("方法执行之前");
Object result = invocation.proceed();
log.info("方法执行完毕");
return result;
}
}
package com.ms.aop.target;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@ComponentScan(basePackageClasses = {Client.class})
@EnableAspectJAutoProxy
public class Client {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Client.class);
IService service = annotationConfigApplicationContext.getBean(IService.class);
service.m1();
}
}
执行结果:
10:49:01.674 [main] INFO com.ms.aop.target.Interceptor1 - 方法执行之前
10:49:01.674 [main] INFO com.ms.aop.target.ServiceImpl - 切入点target测试!
10:49:01.674 [main] INFO com.ms.aop.target.Interceptor1 - 方法执行完毕
this 和 target 的不同点
- this作用于代理对象,target作用于目标对象
- this表示目标对象被代理之后生成的代理对象和指定的类型匹配会被拦截,匹配的是代理对象
- target表示目标对象和指定的类型匹配会被拦截,匹配的是目标对象
5.args 表达式
匹配方法中的参数
@Pointcut("args(com.ms.aop.args.demo1.UserModel)")
匹配只有一个参数,且类型为com.ms.aop.args.demo1.UserModel
匹配多个参数
args(type1,type2,typeN)
匹配任意多个参数
@Pointcut("args(com.ms.aop.args.demo1.UserModel,..)")
匹配第一个参数类型为com.ms.aop.args.demo1.UserModel的所有方法,
..
表示任意个参数
6.@target表达式
匹配的目标对象的类有一个指定的注解
@target(com.ms.aop.jtarget.Annotation1)
目标对象中包含com.ms.aop.jtarget.Annotation1注解,调用该目标对象的任意方法都会被拦截
7.@within表达式
指定匹配必须包含某个注解的类里的所有连接点
@within(com.ms.aop.jwithin.Annotation1)
声明有com.ms.aop.jwithin.Annotation1注解的类中的所有方法都会被拦截
@target 和 @within 的不同点
@target(注解A):判断被调用的目标对象中是否声明了注解A,如果有,会被拦截
@within(注解A): 判断被调用的方法所属的类中是否声明了注解A,如果有,会被拦截
@target关注的是被调用的对象,@within关注的是调用的方法所在的类
8.@annotation表达式
匹配有指定注解的方法(注解作用在方法上面)
@annotation(com.ms.aop.jannotation.demo2.Annotation1)
被调用的方法包含指定的注解
9.@args表达式
方法参数所属的类型上有指定的注解,被匹配
注意:是方法参数所属的类型上有指定的注解,不是方法参数中有注解
- 匹配1个参数,且第1个参数所属的类中有Anno1注解
@args(com.ms.aop.jargs.demo1.Anno1)
- 匹配多个参数,且多个参数所属的类型上都有指定的注解
@args(com.ms.aop.jargs.demo1.Anno1,com.ms.aop.jargs.demo1.Anno2)
- 匹配多个参数,且第一个参数所属的类中有Anno1注解
@args(com.ms.aop.jargs.demo2.Anno1,..)
spring aop中pointcut表达式完整版的更多相关文章
- Spring AOP 中@Pointcut的用法
Spring Aop中@pointCut的用法,格式:execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? nam ...
- Spring AOP中pointcut expression表达式解析
Pointcut 是指那些方法需要被执行"AOP",是由"Pointcut Expression"来描述的. Pointcut可以有下列方式来定义或者通过&am ...
- Spring AOP中pointcut expression表达式解析 及匹配多个条件
Spring中事务控制相关配置: <bean id="txManager" class="org.springframework.jdbc.datasource.D ...
- Spring AOP中pointcut expression表达式
Pointcut 是指那些方法需要被执行"AOP",是由"Pointcut Expression"来描述的. Pointcut可以有下列方式来定义或者通过&am ...
- 转载《Spring AOP中pointcut expression表达式解析 及匹配多个条件》
原文地址:https://www.cnblogs.com/rainy-shurun/p/5195439.html 原文 Pointcut 是指那些方法需要被执行"AOP",是由&q ...
- Spring AOP 中pointcut expression表达式
原文地址——http://blog.csdn.net/qq525099302/article/details/53996344 Pointcut是指那些方法需要被执行”AOP”,是由”Pointcut ...
- Spring AOP 中pointcut expression表达式解析及配置
Pointcut是指那些方法需要被执行”AOP”,是由”Pointcut Expression”来描述的. Pointcut可以有下列方式来定义或者通过&& || 和!的方式进行组合. ...
- Spring AOP中 pointcut expression表达式解析
任意公共方法的执行: execution(public * *(..)) 任何一个以“set”开始的方法的执行: execution(* set*(..)) AccountService 接口的任意方 ...
- Spring AOP 切点(pointcut)表达式
这遍文章将介绍Spring AOP切点表达式(下称表达式)语言,首先介绍两个面向切面编程中使用到的术语. 连接点(Joint Point):广义上来讲,方法.异常处理块.字段这些程序调用过程中可以抽像 ...
随机推荐
- 在Eclipse上Maven环境配置使用
1. 安装配置Maven: 1.1 从Apache网站 http://maven.apache.org/ 下载并且解压缩安装Apache Maven. Maven下载地址: http://maven. ...
- Go语言中的面向对象
前言 如果说最纯粹的面向对象语言,我觉得是Java无疑.而且Java语言的面向对象也是很直观,很容易理解的.class是基础,其他都是要写在class里的. 最近学习了Go语言,有了一些对比和思考.虽 ...
- 浅谈URL跳转与Webview安全
学习信息安全技术的过程中,用开阔的眼光看待安全问题会得到不同的结论. 在一次测试中我用Burpsuite搜索了关键词url找到了某处url,测试一下发现waf拦截了指向外域的请求,于是开始尝试绕过.第 ...
- python中字符串拆分与合并——split()、join()、strip()和replace()
Python3 split()方法 描述split()通过指定分隔符对字符串进行切片,如果参数num 有指定值,则仅分隔 num 个子字符串 语法split()方法语法: str.split(str= ...
- 长沙4月21日开发者大会暨.NET社区成立大会活动纪实
活动总结 2019年4月21日是一个斜风细雨.微风和煦的美好日子,由长沙.NET技术社区.腾讯云云加社区.微软Azure云技术社区.中国.NET技术社区.长沙柳枝行动.长沙互联网活动基地(唐胡子俱乐部 ...
- Vue.js-08:第八章 - 组件的基础知识
一.前言 在之前的学习中,我们对于 Vue 的一些基础语法进行了简单的了解,通过之前的代码可以清晰的看出,我们在使用 Vue 的整个过程,最终都是在对 Vue 实例进行的一系列操作. 这里就会引出一个 ...
- 开箱即用Bumblebee独立部署搭建webapi网关详解
在之前的章节里都是讲述如何在程序中使用Bumblebee来构建一个Webapi网关:但这样显然有些麻烦,毕竟很多时候可能只需要一个简单负载处理,还需要写个程序针对服务进行编写代码或配置的确是比较麻烦的 ...
- Java工程师必备书单
微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...
- Flutter 即学即用系列博客——05 StatelessWidget vs StatefulWidget
前言 上一篇我们对 Flutter UI 有了一个基本的了解. 这一篇我们通过自定义 Widget 来了解下如何写一个 Widget? 然而 Widget 有两个,StatelessWidget 和 ...
- 安卓开发笔记(十三):SQLite数据库储存(下)数据的增添,更改,删除,查询
SQLite数据库存储(下) 1.增添数据 对于添加数据的话我们只需要在主活动当中import新的包以及在主活动当中写上适当的代码就可以了,不需要在我们之前创建新的类当中书写新的代码.现在的主活动 ...