简介

在Spring AOP概述中我们重点注意的是AOP的整体流程和Advice,简化了一些其他的东西,其中就有一些对灵活应用Spring AOP很重要的知识点,例如Pointcut表达式,下面就介绍一下Spring AOP的Pointcut表达式。

如果你对Pointcut表达式的作用还不是很了解,可以先看一下Spring AOP概述,也可以先了解一下匹配规则,后面会有一些具体的例子来帮助理解。

我们使用最多的就是execution表示了,下面就从execution表达式开始介绍吧。

注意:把designators翻译为表达式也许不太合适,所以不必纠结这个问题,只需要知道在看到Spring AOP中的designators知道对应的是个什么东西就可以了。管它是表达式还是指示器只是一个代称而已。

execution表达式

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern)
throws-pattern?)

上面的就是execution表达式的格式,execution匹配的就是连接点(Joinpoint,一般是方法),看上面的表达式execution是固定的,方法的修饰符是可选的,返回类型是必须的,定义的全限类型也是可选的,名称是必须的,参数是必须的,这些都可以使用通配符。

任何的public方法

execution(public * *(..))

以set开始的方法

execution(* set*(..))

定义在cn.freemethod.business.pack.Say接口中的方法

execution(* cn.freemethod.business.pack.Say.*(..))

任何cn.freemethod.business包中的方法

execution(* cn.freemethod.business.*.*(..))

任何定义在com.xyz.service包或者其子包中的方法

execution(* cn.freemethod.business..*.*(..))

其他表达式

任何在com.xyz.service包中的方法

within(com.xyz.service.*)

任何定义在com.xyz.service包或者其子包中的方法

within(com.xyz.service..*)

任何实现了com.xyz.service.AccountService接口中的方法

this(com.xyz.service.AccountService)

任何目标对象实现了com.xyz.service.AccountService的方法

target(com.xyz.service.AccountService)

一般情况下代理类(Proxy)和目标类(Target)都实现了相同的接口,所以上面的2个基本是等效的。


有且只有一个Serializable参数的方法

args(java.io.Serializable)

只要这个参数实现了java.io.Serializable接口就可以,不管是java.io.Serializable还是Integer,还是String都可以。

目标(target)使用了@Transactional注解的方法

@target(org.springframework.transaction.annotation.Transactional)

目标类(target)如果有Transactional注解中的所有方法

@within(org.springframework.transaction.annotation.Transactional)

任何方法有Transactional注解的方法

@annotation(org.springframework.transaction.annotation.Transactional)

有且仅有一个参数并且参数上类型上有Transactional注解

@args(org.springframework.transaction.annotation.Transactional)

注意是参数类型上有Transactional注解,而不是方法的参数上有注解。

-- bean的名字为tradeService中的方法

 bean(simpleSay)
bean名字为simpleSay中的所有方法。

-- bean名字能匹配

bean(*Impl)
bean名字匹配*Impl的bean中的所有方法。

实例

这个实例是对Spring AOP概述中介绍的实例进行了扩展。当然下面给的实例也可以独立测试,最好是一个一个测试观察输出了验证,多个输出结果不够直观。

下面的图片是项目工程目录结构:

下面的代码列表因为比较多,只能展示部分代码。

--OtherPointcutAspect:

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.Aspect;

import org.springframework.stereotype.Component;

@Component

@Aspect

public class OtherPointcutAspect {

// @After("cn.freemethod.pointcut.OtherPointcut.argsSerializable()")

public void argsSerialize(){

System.out.println("OtherPointcutAspect argsSerialize after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.inBusinessPackage()")

public void inBusinessPackage(){

System.out.println("OtherPointcutAspect inBusinessPackage after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.inBusinessOrSubPackage()")

public void inBusinessOrSubPackage(){

System.out.println("OtherPointcutAspect inBusinessOrSubPackage after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.proxyImplementHaveResultBusinessInteferce()")

public void proxyImplementHaveResultBusinessInteferce(){

System.out.println("OtherPointcutAspect proxyImplementHaveResultBusinessInteferce after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.targetImplementBusinessInteferce()")

public void targetImplementBusinessInteferce(){

System.out.println("OtherPointcutAspect targetImplementBusinessInteferce after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.targetHaveTransactional()")

public void targetHaveTransactional(){

System.out.println("OtherPointcutAspect targetHaveTransactional after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.targetDeclareHaveTransactional()")

public void targetDeclareHaveTransactional(){

System.out.println("OtherPointcutAspect targetDeclareHaveTransactional after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.methodHaveTransactional()")

public void methodHaveTransactional(){

System.out.println("OtherPointcutAspect methodHaveTransactional after...");

}

@After("cn.freemethod.pointcut.OtherPointcut.argsHaveValueAnnotation()")
public void argsHaveTransactional(){
System.out.println("OtherPointcutAspect argsHaveValueAnnotation after...");
}

// @After("cn.freemethod.pointcut.OtherPointcut.beanName()")

public void beanName(){

System.out.println("OtherPointcutAspect beanName after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.matchBeanName()")

public void matchBeanName(){

System.out.println("OtherPointcutAspect matchBeanName after...");

}

}

上面是一个测试Pointcut表达式的切面,很多Advice都注释了,请为了从输出中直观的了解Pointcut表达式匹配到了什么方法(Joinpoint),请根据自己的需要测试的Pointcut表达式取消添加注释。

--ExecutionPointcutAspect:

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.AfterReturning;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.springframework.stereotype.Component;

@Component

@Aspect

public class ExecutionPointcutAspect {

@Before("cn.freemethod.pointcut.ExecutionPointcut.allPublicMethod()")
public void allPublicBefore(){
System.out.println("PointcutExpressionAspect allPublicBefore...");
} @After("cn.freemethod.pointcut.ExecutionPointcut.allStartSayMethod()")
public void sayAfter(){
System.out.println("PointcutExpressionAspect sayAfter...");
} @AfterReturning("cn.freemethod.pointcut.ExecutionPointcut.allInSayInterfaceMethod()")
public void allInSayInterfaceMethod(){
System.out.println("PointcutExpressionAspect allInSayInterfaceMethod...");
} @Before("cn.freemethod.pointcut.ExecutionPointcut.allInBusinessPackage()")
public void allInBusinessPackageBefore(){
System.out.println("PointcutExpressionAspect all business before...");
} @After("cn.freemethod.pointcut.ExecutionPointcut.allInBusinessOrSubPackage()")
public void allallInBusinessOrSubPackageAfter(){
System.out.println("PointcutExpressionAspect allallInBusinessOrSubPackageAfter...");
}

}

---ParamBean:

import org.springframework.transaction.annotation.Transactional;

@Transactional

public class ParamBean {

}

--HaveResultBusinessImpl:

import org.springframework.stereotype.Service;

import cn.freemethod.business.HaveResultBusiness;

@Service

public class HaveResultBusinessImpl implements HaveResultBusiness {

@Override
public Integer getResult(Integer div) {
System.out.println("HaveResultBusinessImpl getResult");
Integer result = 100 / div;
return result;
}

}

--IOtherPointcutImpl:

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import cn.freemethod.bean.ParamBean;

import cn.freemethod.business.pack.IOtherPointcut;

@Transactional

@Service

public class IOtherPointcutImpl implements IOtherPointcut {

@Override
public Integer printInteger(Integer arg) {
System.out.println("IOtherPointcutImpl printInteger");
return arg;
} @Override
public void withAnotationParam(ParamBean arg) {
System.out.println("IOtherPointcutImpl withAnotationParam");
}

}

--SimpleSay:

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import cn.freemethod.business.pack.Say;

@Transactional

@Service

public class SimpleSay implements Say {

@Override
public String sayChiness(String name) {
String result = "你好:" + name;
System.out.println(result);
return result;
} @Override
public String sayEnglish(String name) {
String result = "Hello " + name;
System.out.println(result);
return result;
} @Transactional
@Override
public String whatSay() {
System.out.println("what say");
return "what say";
}

}

--IOtherPointcut:

import cn.freemethod.bean.ParamBean;

public interface IOtherPointcut {

Integer printInteger(Integer arg);

void withAnotationParam(ParamBean arg);

}

--Say:

public interface Say {

String sayChiness(String name);

String sayEnglish(String name);

String whatSay();

}

--HaveResultBusiness:

public interface HaveResultBusiness {

Integer getResult(Integer div);

}

--AspectConfig:

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration

@EnableAspectJAutoProxy

@ComponentScan(basePackages = {"cn.freemethod"})

public class AspectConfig {

}

--ExecutionPointcut:

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Pointcut;

@Aspect

public class ExecutionPointcut {

@Pointcut("execution(public * *(..))")
public void allPublicMethod(){} @Pointcut("execution(* say*(..))")
public void allStartSayMethod(){} @Pointcut("execution(* cn.freemethod.business.pack.Say.*(..))")
public void allInSayInterfaceMethod(){} @Pointcut("execution(* cn.freemethod.business.*.*(..))")
public void allInBusinessPackage(){} @Pointcut("execution(* cn.freemethod.business..*.*(..))")
public void allInBusinessOrSubPackage(){}

}

--OtherPointcut :

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Pointcut;

@Aspect

public class OtherPointcut {

@Pointcut("within(cn.freemethod.business.impl.*)")
public void inBusinessPackage(){} @Pointcut("within(cn.freemethod.business..*)")
public void inBusinessOrSubPackage(){} @Pointcut("this(cn.freemethod.business.HaveResultBusiness)")
public void proxyImplementHaveResultBusinessInteferce(){} @Pointcut("target(cn.freemethod.business.HaveResultBusiness)")
public void targetImplementBusinessInteferce(){} @Pointcut("args(java.io.Serializable)")

// @Pointcut("args(java.lang.Integer)")

public void argsSerializable(){}

@Pointcut("@target(org.springframework.transaction.annotation.Transactional)")
public void targetHaveTransactional(){} @Pointcut("@within(org.springframework.transaction.annotation.Transactional)")
public void targetDeclareHaveTransactional(){} @Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)")
public void methodHaveTransactional(){} @Pointcut("@args(org.springframework.transaction.annotation.Transactional)")
public void argsHaveValueAnnotation(){} @Pointcut("bean(simpleSay)")
public void beanName(){} @Pointcut("bean(*Impl)")
public void matchBeanName(){}

}

--AnnotationConfigStart:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import org.springframework.context.support.AbstractApplicationContext;

import cn.freemethod.business.HaveResultBusiness;

import cn.freemethod.business.pack.Say;

import cn.freemethod.config.AspectConfig;

public class AnnotationConfigStart {

public static void main(String[] args) {
AbstractApplicationContext context = new AnnotationConfigApplicationContext(AspectConfig.class);
HaveResultBusiness haveResultBusiness = context.getBean(HaveResultBusiness.class);
haveResultBusiness.getResult(100);
Say say = context.getBean(Say.class);
say.sayChiness("tim");
say.sayEnglish("tim");
say.whatSay();
context.close();
}

}

--PointcutExpressionStart:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import org.springframework.context.support.AbstractApplicationContext;

import cn.freemethod.bean.ParamBean;

import cn.freemethod.business.HaveResultBusiness;

import cn.freemethod.business.pack.IOtherPointcut;

import cn.freemethod.business.pack.Say;

import cn.freemethod.config.AspectConfig;

public class PointcutExpressionStart {

public static void main(String[] args) {
AbstractApplicationContext context = new AnnotationConfigApplicationContext(AspectConfig.class);
IOtherPointcut iOtherPointcut = context.getBean(IOtherPointcut.class);
iOtherPointcut.printInteger(new Integer(10));
iOtherPointcut.withAnotationParam(new ParamBean()); HaveResultBusiness haveResultBusiness = context.getBean(HaveResultBusiness.class);
haveResultBusiness.getResult(100); Say say = context.getBean(Say.class);
say.sayChiness("tim");
say.sayEnglish("tim");
say.whatSay();
context.close();
}

}

Spring AOP 之二:Pointcut注解表达式的更多相关文章

  1. spring AOP 之二:@AspectJ注解的3种配置

    @AspectJ相关文章 <spring AOP 之二:@AspectJ注解的3种配置> <spring AOP 之三:使用@AspectJ定义切入点> <spring ...

  2. 深入理解Spring AOP之二代理对象生成

    深入理解Spring AOP之二代理对象生成 spring代理对象 上一篇博客中讲到了Spring的一些基本概念和初步讲了实现方法,当中提到了动态代理技术,包含JDK动态代理技术和Cglib动态代理 ...

  3. Spring Aop(二)——基于Aspectj注解的Spring Aop简单实现

    转发地址:https://www.iteye.com/blog/elim-2394762 2 基于Aspectj注解的Spring Aop简单实现 Spring Aop是基于Aop框架Aspectj实 ...

  4. Spring AOP中使用@Aspect注解 面向切面实现日志横切功能详解

    引言: AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一 ...

  5. 【Spring AOP】Spring AOP之如何通过注解的方式实现各种通知类型的AOP操作进阶篇(3)

    一.切入点表达式的各种类型 切入点表达式的作用:限制连接点的匹配(满足时对应的aspect方法会被执行) 1)execution:用于匹配方法执行连接点.Spring AOP用户可能最经常使用exec ...

  6. spring AOP (使用AspectJ的注解方式 的aop实现) (6)

    目录 一.在 Spring 中启用 AspectJ 注解支持 二.AspectJ 支持 5 种类型的通知注解: 2.1.使用之前的 计算器接口和实现类 ArithmeticCalculator.jav ...

  7. Spring AOP(5)-- 注解

    applicationContext.xml <?xml version="1.0" encoding="UTF-8"?><beans xml ...

  8. Spring学习十五----------Spring AOP API的Pointcut、advice及 ProxyFactoryBean相关内容

    © 版权声明:本文为博主原创文章,转载请注明出处 实例: 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4. ...

  9. Spring AOP编程(二)-AOP实现的三种方式

    AOP的实现有三种方式: l         aop底层将采用代理机制进行实现. l         接口 + 实现类 :spring采用 jdk 的动态代理Proxy. l         实现类: ...

随机推荐

  1. 论文阅读:Reducing Transformer Depth On Demand With Structured Dropout

    Introduction 这篇paper是做Transformer压缩的,但其实bert的核心也就是transformer,这篇paper的实验里也做了bert的压缩.作者的主要工作是提出了Layer ...

  2. 30分钟快速上手Docker,看这篇就对了!

    一.历史演化 1.演化史 2.物理机时代 2.1.图解 一个物理机上安装操作系统,然后直接运行我们的软件.也就是说你电脑上直接跑了一个软件,并没有开虚拟机什么的,资源极其浪费. 2.2.缺点 部署慢 ...

  3. Node.js NPM Tutorial: Create, Publish, Extend & Manage

    A module in Node.js is a logical encapsulation of code in a single unit. It's always a good programm ...

  4. Jumpserver-跳板机的搭建

    Jumpserver堡垒机 一.Jumpserver堡垒机概述-部署Jumpserver运行环境 01 跳板机概述 跳板机就是一台服务器,开发或运维人员在维护过程中首先要统一登录到这台服务器,然后再登 ...

  5. 监控-zabbix

    1:什么是监控? 监控:安防的监控  看监控,事后追责 linux监控: 事前预警,数据分析 2:常见的linux监控命令 cpu             1 top 2 htop 3 uptime ...

  6. go模板-代码生成器

    能用程序去做的事,就不要用手,编写自己的代码生成器就是用来解放你的双手,替你做一些重复性的工作. 上篇帖子写了模板的基础 go模板详说 ,有了基础就要做点什么东西,把所学到的东西应用起来才能更好的进步 ...

  7. 【软工】[技术博客] 用Monaco Editor打造接近vscode体验的浏览器IDE

    [技术博客] 用Monaco Editor打造接近vscode体验的浏览器IDE 官方文档与重要参考资料 官方demo 官方API调用样例 Playground 官方API Doc,但其搜索框不支持模 ...

  8. [PHP工具推荐]0001.分析和解析代码的7大工具

    引言:PHP已成为时下最热门的编程语言之一,然而却有许多PHP程序员苦恼找不到合适的工具来帮助自己分析和解析PHP代码.今天SD就为大家介绍几个非常不错的工具,来帮助程序员们提高自己的工作效率,一起来 ...

  9. Linux 任务后台运行软件【即:终端复用器】之---screen

    会话: 命令行的典型使用方式是,打开一个终端窗口(terminal window,以下简称"窗口"),在里面输入命令. 用户与计算机的这种临时的交互,称为一次"会话&qu ...

  10. 编译sifive的freedom-u-sdk

    在其它电脑搭建编译该sdk工程的环境,由于所在电脑的linux系统为新装系统(版本:Ubuntu 20.04 LTS),下面记录了编译过程中遇到的问题,以及解决过程供以后参考 问题1:error &q ...