spring aop中pointcut表达式
spring aop中pointcut表达式
本文主要介绍spring aop中9种切入点表达式的写法
- execute
- within
- this
- target
- args
- @target
- @within
- @annotation
- @args
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.yezi.aop.jthis.demo1;public interface IService {void m1();
}
package com.yezi.aop.jthis.demo1;import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;@Slf4j
@Component
public class ServiceImpl implements IService {@Overridepublic void m1() {log.info("切入点this测试!");}
}
package com.yezi.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.yezi.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.yezi.aop.jthis.demo1.ServiceImpl - 切入点this测试!
10:27:12.277 [main] INFO com.yezi.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.yezi.aop.jthis.demo1.Interceptor1 - 方法执行之前 10:34:50.755 [main] INFO com.yezi.aop.jthis.demo1.ServiceImpl - 切入点this测试! 10:34:50.756 [main] INFO com.yezi.aop.jthis.demo1.Interceptor1 - 方法执行完毕 10:34:50.756 [main] INFO com.yezi.aop.jthis.demo1.Client - true
service 为 ServiceImpl类型的对象,所以会被拦截
4.target表达式
目标对象为指定的类型被拦截
target(com.xyz.service.AccountService)
目标对象为AccountService类型的会被代理
示例
package com.yezi.aop.target;public interface IService {void m1();
}
package com.yezi.aop.target;import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;@Slf4j
@Component
public class ServiceImpl implements IService {@Overridepublic void m1() {log.info("切入点target测试!");}
}
package com.yezi.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.yezi.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.yezi.aop.target.Interceptor1 - 方法执行之前
10:49:01.674 [main] INFO com.yezi.aop.target.ServiceImpl - 切入点target测试!
10:49:01.674 [main] INFO com.yezi.aop.target.Interceptor1 - 方法执行完毕
this 和 target 的不同点
- this作用于代理对象,target作用于目标对象
- this表示目标对象被代理之后生成的代理对象和指定的类型匹配会被拦截,匹配的是代理对象
- target表示目标对象和指定的类型匹配会被拦截,匹配的是目标对象
5.args 表达式
匹配方法中的参数
@Pointcut("args(com.yezi.aop.args.demo1.UserModel)")
匹配只有一个参数,且类型为com.ms.aop.args.demo1.UserModel
匹配多个参数
args(type1,type2,typeN)
匹配任意多个参数
@Pointcut("args(com.yezi.aop.args.demo1.UserModel,..)")
匹配第一个参数类型为com.ms.aop.args.demo1.UserModel的所有方法,
..
表示任意个参数
6.@target表达式
匹配的目标对象的类有一个指定的注解
@target(com.yezi.aop.jtarget.Annotation1)
目标对象中包含com.ms.aop.jtarget.Annotation1注解,调用该目标对象的任意方法都会被拦截
7.@within表达式
指定匹配必须包含某个注解的类里的所有连接点
@within(com.yezi.aop.jwithin.Annotation1)
声明有com.ms.aop.jwithin.Annotation1注解的类中的所有方法都会被拦截
@target 和 @within 的不同点
@target(注解A):判断被调用的目标对象中是否声明了注解A,如果有,会被拦截
@within(注解A): 判断被调用的方法所属的类中是否声明了注解A,如果有,会被拦截
@target关注的是被调用的对象,@within关注的是调用的方法所在的类
8.@annotation表达式
匹配有指定注解的方法(注解作用在方法上面)
@annotation(com.yezi.aop.jannotation.demo2.Annotation1)
被调用的方法包含指定的注解
9.@args表达式
方法参数所属的类型上有指定的注解,被匹配
注意:是方法参数所属的类型上有指定的注解,不是方法参数中有注解
- 匹配1个参数,且第1个参数所属的类中有Anno1注解
@args(com.yezi.aop.jargs.demo1.Anno1)
- 匹配多个参数,且多个参数所属的类型上都有指定的注解
@args(com.yezi.aop.jargs.demo1.Anno1,com.ms.aop.jargs.demo1.Anno2)
- 匹配多个参数,且第一个参数所属的类中有Anno1注解
@args(com.yezi.aop.jargs.demo2.Anno1,..)
spring aop中pointcut表达式相关推荐
- Spring AOP中pointcut 切点详解
Spring AOP中pointcut 是指那些方法需要被执行"AOP",是由"Pointcut Expression"来描述的. Pointcut可以有下列方 ...
- Spring AOP中Pointcut,dvice 和 Advisor三个概念
Spring AOP中Pointcut,dvice 和 Advisor三个概念介绍 在理解了Spring的AOP后,需要重点理解的三个概念是:Pointcut Advice Advisor ...
- Spring AOP 切点 Pointcut 表达式介绍与使用
一.前言 面向切面编程 AOP 是一种常见的编程思想,是面向对象编程的一种补充,AOP 框架通过修改源代码,将处理逻辑编织到指定的业务模块中 常见的处理比如:在方执行法前进行校验,在方法执行后进行日志 ...
- SpringBoot的AOP中PointCut表达式详解以及使用
首先,在pom.xml中添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifa ...
- Spring AOP中pointcut expression表达式解析 及匹配多个条件
(* com.evan.crm.service.*.*(..))中几个通配符的含义: |第一个 * -- 通配 随便率性返回值类型| |第二个 * -- 通配包com.evan.crm.servic ...
- Spring AOP中@Pointcut切入点表达式详解
目录 一.瞅一眼标准的AspectJ Aop的pointcut的表达式 二.SpringAop的十一种AOP表达式 三.演示使用 1.execution: 2.within: 3.this: 4.ta ...
- Spring AOP中pointcut expression表达式解析
Pointcut 是指那些方法需要被执行"AOP",是由"Pointcut Expression"来描述的. Pointcut可以有下列方式来定义或者通过&am ...
- Spring AOP 切点(pointcut)表达式
概括 这遍文章将介绍Spring AOP切点表达式(下称表达式)语言,首先介绍两个面向切面编程中使用到的术语. 连接点(Joint Point):广义上来讲,方法.异常处理块.字段这些程序调用过程中可 ...
- SpringAOP专题之6、Spring AOP中@Pointcut 12种用法
本文主要内容:掌握@Pointcut的12种用法. Aop相关阅读 阅读本文之前,需要先掌握下面几篇篇文章内容,不然会比较吃力. 代理详解(java动态代理&CGLIB代理) jdk动态代理和 ...
最新文章
- mysql 语句 求比值_Mysql求百分比
- 利用Eclipse的JPA自动生成注解实体
- JavaScript实现squareRoot平方根算法(附完整源码)
- terminated 线程_深入并发,线程相关知识全解析
- 【j2ee spring】30、巴巴荆楚网-综合hibernate4+spring4(5)分页
- Xamarin开发笔记—设备类第三方弹窗的使用和注意事项
- 不要在循环,条件或嵌套函数中调用 Hook
- better-scroll在vue中的使用
- 程序员开发的“逆天”软件
- 快速上手数据挖掘之Solr5搜索引擎高级教程
- Jquery UI 教程
- 零基础怎样自学编程?初学者如何学习编程?编程学习入门指南(文章较长,需要耐心看完)
- Synchronized和Reentrantlock的区别
- 局域网共享一键修复(转载)
- VLAN vs. VXLAN:云时代下各施所长
- NC91 最长递增子序列
- 如何用Yii2编程:ActiveRecord
- opengl SwapBuffers的等待,虚伪的FPS
- 阿里巴巴内推一面过程
- Asp.Net MVC4的学习概况