spring aop中pointcut表达式完整版

本文主要介绍spring aop中9种切入点表达式的写法

  1. execute
  2. within
  3. this
  4. target
  5. args
  6. @target
  7. @within
  8. @annotation
  9. @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
  1. @EnableAspectJAutoProxy:表示若spring创建的对象如果实现了接口,默认使用jdk动态代理,如果没有实现接口,使用cglib创建代理对象

  2. 所以 service 是使用jdk动态代理生成的对象,service instanceof ServiceImplfalse

  3. @Pointcut("this(com.ms.aop.jthis.demo1.ServiceImpl)")表示被spring代理之后生成的对象必须为com.ms.aop.jthis.demo1.ServiceImpl才会被拦截,但是service不是ServiceImpl类型的对象了,所以不会被拦截

  4. 修改代码

    @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 的不同点

  1. this作用于代理对象,target作用于目标对象
  2. this表示目标对象被代理之后生成的代理对象和指定的类型匹配会被拦截,匹配的是代理对象
  3. 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 的不同点

  1. @target(注解A):判断被调用的目标对象中是否声明了注解A,如果有,会被拦截

  2. @within(注解A): 判断被调用的方法所属的类中是否声明了注解A,如果有,会被拦截

  3. @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表达式完整版的更多相关文章

  1. Spring AOP 中@Pointcut的用法

    Spring Aop中@pointCut的用法,格式:execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? nam ...

  2. Spring AOP中pointcut expression表达式解析

    Pointcut 是指那些方法需要被执行"AOP",是由"Pointcut Expression"来描述的. Pointcut可以有下列方式来定义或者通过&am ...

  3. Spring AOP中pointcut expression表达式解析 及匹配多个条件

    Spring中事务控制相关配置: <bean id="txManager" class="org.springframework.jdbc.datasource.D ...

  4. Spring AOP中pointcut expression表达式

    Pointcut 是指那些方法需要被执行"AOP",是由"Pointcut Expression"来描述的. Pointcut可以有下列方式来定义或者通过&am ...

  5. 转载《Spring AOP中pointcut expression表达式解析 及匹配多个条件》

    原文地址:https://www.cnblogs.com/rainy-shurun/p/5195439.html 原文 Pointcut 是指那些方法需要被执行"AOP",是由&q ...

  6. Spring AOP 中pointcut expression表达式

    原文地址——http://blog.csdn.net/qq525099302/article/details/53996344 Pointcut是指那些方法需要被执行”AOP”,是由”Pointcut ...

  7. Spring AOP 中pointcut expression表达式解析及配置

    Pointcut是指那些方法需要被执行”AOP”,是由”Pointcut Expression”来描述的. Pointcut可以有下列方式来定义或者通过&& || 和!的方式进行组合. ...

  8. Spring AOP中 pointcut expression表达式解析

    任意公共方法的执行: execution(public * *(..)) 任何一个以“set”开始的方法的执行: execution(* set*(..)) AccountService 接口的任意方 ...

  9. Spring AOP 切点(pointcut)表达式

    这遍文章将介绍Spring AOP切点表达式(下称表达式)语言,首先介绍两个面向切面编程中使用到的术语. 连接点(Joint Point):广义上来讲,方法.异常处理块.字段这些程序调用过程中可以抽像 ...

随机推荐

  1. 基于 HTML5 的 WebGL 3D 版俄罗斯方块

    前言 摘要:2D 的俄罗斯方块已经被人玩烂了,突发奇想就做了个 3D 的游戏机,用来玩俄罗斯方块...实现的基本想法是先在 2D 上实现俄罗斯方块小游戏,然后使用 3D 建模功能创建一个 3D 街机模 ...

  2. Python爬虫入门教程 64-100 反爬教科书级别的网站-汽车之家,字体反爬之二

    说说这个网站 汽车之家,反爬神一般的存在,字体反爬的鼻祖网站,这个网站的开发团队,一定擅长前端吧,2019年4月19日开始写这篇博客,不保证这个代码可以存活到月底,希望后来爬虫coder,继续和汽车之 ...

  3. Actor模型及原理

    1.Actor模型 在使用Java进行并发编程时需要特别的关注锁和内存原子性等一系列线程问题,而Actor模型内部的状态由它自己维护即它内部数据只能由它自己修改(通过消息传递来进行状态修改),所以使用 ...

  4. 我眼中的 Nginx(五):Nginx — 子请求设计之道

    张超:又拍云系统开发高级工程师,负责又拍云 CDN 平台相关组件的更新及维护.Github ID: tokers,活跃于 OpenResty 社区和 Nginx 邮件列表等开源社区,专注于服务端技术的 ...

  5. SignalR第一节-在5分钟内完成通信连接和消息发送

    前言 首先声明,这又是一个小白从入门到进阶系列. SignalR 这个项目我关注了很长时间,中间好像还看到过微软即将放弃该项目的消息,然后我也就没有持续关注了,目前的我项目中使用的是自己搭建的 Web ...

  6. Java PDF页面设置——页面大小、页边距、纸张方向、页面旋转

    下面的示例将介绍通过Java编程来对PDF页面进行个性化设置的方法,包括设置页面大小.页边距.纸张方向.页面旋转等.这里有如下多种页面大小尺寸可供选择: 同时,设置文档内容旋转时,可支持如下角度进行内 ...

  7. 03. Redis-配置文件

    redis-3.2.6配置文件 主要修改配置文件几个大方面: 端口 port 安全: bind ip 绑定监听IP 安全模式开启与否 protected-mode 一般设置yes 访问密码 requi ...

  8. Android调试神器stetho使用详解和改造

    本文由云+社区发表 作者:NaOH 概述 stetho是Facebook开源的一个Android调试工具,项目地址:facebook/stetho 通过Stetho,开发者可以使用chrome的ins ...

  9. 删除Oracle用户及表空间

    --转载自 https://blog.csdn.net/sunny05296/article/details/81126548--以sysdba用户登录,查找需要删除的用户conn / as sysd ...

  10. Redis Sentinel集群双机房容灾实施步骤

    概要目标防止双机房情况下任一个机房完全无法提供服务时如何让Redis继续提供服务.架构设计A.B两机房,其中A机房有一Master一Slave和两个Sentinel,B机房只有2个Sentinel,如 ...