Spring AOP 之二:Pointcut注解表达式

简介

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

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

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

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

execution表达式

1execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) 2throws-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概述中介绍的实例进行了扩展。当然下面给的实例也可以独立测试,最好是一个一个测试观察输出了验证,多个输出结果不够直观。

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

工程目录结构

下面的代码列表因为比较多,可以在后面找到完整的代码工程代码的附件链接,因为其他一些原因没有放到github或者码云上,可以直接下载附件解压使用maven方式导入。

OtherPointcutAspect

1import org.aspectj.lang.annotation.After; 2import org.aspectj.lang.annotation.Aspect; 3import org.springframework.stereotype.Component; 4 5@Component 6@Aspect 7public class OtherPointcutAspect { 8 9// @After("cn.freemethod.pointcut.OtherPointcut.argsSerializable()") 10 public void argsSerialize(){ 11 System.out.println("OtherPointcutAspect argsSerialize after..."); 12 } 13 14// @After("cn.freemethod.pointcut.OtherPointcut.inBusinessPackage()") 15 public void inBusinessPackage(){ 16 System.out.println("OtherPointcutAspect inBusinessPackage after..."); 17 } 18 19// @After("cn.freemethod.pointcut.OtherPointcut.inBusinessOrSubPackage()") 20 public void inBusinessOrSubPackage(){ 21 System.out.println("OtherPointcutAspect inBusinessOrSubPackage after..."); 22 } 23 24// @After("cn.freemethod.pointcut.OtherPointcut.proxyImplementHaveResultBusinessInteferce()") 25 public void proxyImplementHaveResultBusinessInteferce(){ 26 System.out.println("OtherPointcutAspect proxyImplementHaveResultBusinessInteferce after..."); 27 } 28 29// @After("cn.freemethod.pointcut.OtherPointcut.targetImplementBusinessInteferce()") 30 public void targetImplementBusinessInteferce(){ 31 System.out.println("OtherPointcutAspect targetImplementBusinessInteferce after..."); 32 } 33 34// @After("cn.freemethod.pointcut.OtherPointcut.targetHaveTransactional()") 35 public void targetHaveTransactional(){ 36 System.out.println("OtherPointcutAspect targetHaveTransactional after..."); 37 } 38 39// @After("cn.freemethod.pointcut.OtherPointcut.targetDeclareHaveTransactional()") 40 public void targetDeclareHaveTransactional(){ 41 System.out.println("OtherPointcutAspect targetDeclareHaveTransactional after..."); 42 } 43 44// @After("cn.freemethod.pointcut.OtherPointcut.methodHaveTransactional()") 45 public void methodHaveTransactional(){ 46 System.out.println("OtherPointcutAspect methodHaveTransactional after..."); 47 } 48 49 @After("cn.freemethod.pointcut.OtherPointcut.argsHaveValueAnnotation()") 50 public void argsHaveTransactional(){ 51 System.out.println("OtherPointcutAspect argsHaveValueAnnotation after..."); 52 } 53 54// @After("cn.freemethod.pointcut.OtherPointcut.beanName()") 55 public void beanName(){ 56 System.out.println("OtherPointcutAspect beanName after..."); 57 } 58 59// @After("cn.freemethod.pointcut.OtherPointcut.matchBeanName()") 60 public void matchBeanName(){ 61 System.out.println("OtherPointcutAspect matchBeanName after..."); 62 } 63 64}

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

ExecutionPointcutAspect

1import org.aspectj.lang.annotation.After; 2import org.aspectj.lang.annotation.AfterReturning; 3import org.aspectj.lang.annotation.Aspect; 4import org.aspectj.lang.annotation.Before; 5import org.springframework.stereotype.Component; 6 7@Component 8@Aspect 9public class ExecutionPointcutAspect { 10 11 @Before("cn.freemethod.pointcut.ExecutionPointcut.allPublicMethod()") 12 public void allPublicBefore(){ 13 System.out.println("PointcutExpressionAspect allPublicBefore..."); 14 } 15 16 @After("cn.freemethod.pointcut.ExecutionPointcut.allStartSayMethod()") 17 public void sayAfter(){ 18 System.out.println("PointcutExpressionAspect sayAfter..."); 19 } 20 21 @AfterReturning("cn.freemethod.pointcut.ExecutionPointcut.allInSayInterfaceMethod()") 22 public void allInSayInterfaceMethod(){ 23 System.out.println("PointcutExpressionAspect allInSayInterfaceMethod..."); 24 } 25 26 @Before("cn.freemethod.pointcut.ExecutionPointcut.allInBusinessPackage()") 27 public void allInBusinessPackageBefore(){ 28 System.out.println("PointcutExpressionAspect all business before..."); 29 } 30 31 @After("cn.freemethod.pointcut.ExecutionPointcut.allInBusinessOrSubPackage()") 32 public void allallInBusinessOrSubPackageAfter(){ 33 System.out.println("PointcutExpressionAspect allallInBusinessOrSubPackageAfter..."); 34 } 35 36}

ParamBean

1import org.springframework.transaction.annotation.Transactional; 2 3@Transactional 4public class ParamBean { 5 6}

HaveResultBusinessImpl

1import org.springframework.stereotype.Service; 2 3import cn.freemethod.business.HaveResultBusiness; 4 5@Service 6public class HaveResultBusinessImpl implements HaveResultBusiness { 7 8 @Override 9 public Integer getResult(Integer div) { 10 System.out.println("HaveResultBusinessImpl getResult"); 11 Integer result = 100 / div; 12 return result; 13 } 14 15}

IOtherPointcutImpl

1import org.springframework.stereotype.Service; 2import org.springframework.transaction.annotation.Transactional; 3 4import cn.freemethod.bean.ParamBean; 5import cn.freemethod.business.pack.IOtherPointcut; 6 7@Transactional 8@Service 9public class IOtherPointcutImpl implements IOtherPointcut { 10 11 @Override 12 public Integer printInteger(Integer arg) { 13 System.out.println("IOtherPointcutImpl printInteger"); 14 return arg; 15 } 16 17 18 @Override 19 public void withAnotationParam(ParamBean arg) { 20 System.out.println("IOtherPointcutImpl withAnotationParam"); 21 } 22 23}

SimpleSay

1import org.springframework.stereotype.Service; 2import org.springframework.transaction.annotation.Transactional; 3 4import cn.freemethod.business.pack.Say; 5 6@Transactional 7@Service 8public class SimpleSay implements Say { 9 10 @Override 11 public String sayChiness(String name) { 12 String result = "你好:" + name; 13 System.out.println(result); 14 return result; 15 } 16 17 @Override 18 public String sayEnglish(String name) { 19 String result = "Hello " + name; 20 System.out.println(result); 21 return result; 22 } 23 24 @Transactional 25 @Override 26 public String whatSay() { 27 System.out.println("what say"); 28 return "what say"; 29 } 30 31} 32

IOtherPointcut

1import cn.freemethod.bean.ParamBean; 2 3public interface IOtherPointcut { 4 5 Integer printInteger(Integer arg); 6 7 void withAnotationParam(ParamBean arg); 8 9}

Say

1public interface Say { 2 3 String sayChiness(String name); 4 5 String sayEnglish(String name); 6 7 String whatSay(); 8 9}

HaveResultBusiness

1public interface HaveResultBusiness { 2 3 Integer getResult(Integer div); 4 5}

AspectConfig

1import org.springframework.context.annotation.ComponentScan; 2import org.springframework.context.annotation.Configuration; 3import org.springframework.context.annotation.EnableAspectJAutoProxy; 4 5@Configuration 6@EnableAspectJAutoProxy 7@ComponentScan(basePackages = {"cn.freemethod"}) 8public class AspectConfig { 9 10}

ExecutionPointcut

1import org.aspectj.lang.annotation.Aspect; 2import org.aspectj.lang.annotation.Pointcut; 3 4@Aspect 5public class ExecutionPointcut { 6 7 @Pointcut("execution(public * *(..))") 8 public void allPublicMethod(){} 9 10 @Pointcut("execution(* say*(..))") 11 public void allStartSayMethod(){} 12 13 @Pointcut("execution(* cn.freemethod.business.pack.Say.*(..))") 14 public void allInSayInterfaceMethod(){} 15 16 @Pointcut("execution(* cn.freemethod.business.*.*(..))") 17 public void allInBusinessPackage(){} 18 19 @Pointcut("execution(* cn.freemethod.business..*.*(..))") 20 public void allInBusinessOrSubPackage(){} 21 22 23} 24 25 26 27import org.aspectj.lang.annotation.Aspect; 28import org.aspectj.lang.annotation.Pointcut; 29 30@Aspect 31public class OtherPointcut { 32 33 @Pointcut("within(cn.freemethod.business.impl.*)") 34 public void inBusinessPackage(){} 35 36 @Pointcut("within(cn.freemethod.business..*)") 37 public void inBusinessOrSubPackage(){} 38 39 @Pointcut("this(cn.freemethod.business.HaveResultBusiness)") 40 public void proxyImplementHaveResultBusinessInteferce(){} 41 42 @Pointcut("target(cn.freemethod.business.HaveResultBusiness)") 43 public void targetImplementBusinessInteferce(){} 44 45 @Pointcut("args(java.io.Serializable)") 46// @Pointcut("args(java.lang.Integer)") 47 public void argsSerializable(){} 48 49 50 @Pointcut("@target(org.springframework.transaction.annotation.Transactional)") 51 public void targetHaveTransactional(){} 52 53 @Pointcut("@within(org.springframework.transaction.annotation.Transactional)") 54 public void targetDeclareHaveTransactional(){} 55 56 @Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)") 57 public void methodHaveTransactional(){} 58 59 @Pointcut("@args(org.springframework.transaction.annotation.Transactional)") 60 public void argsHaveValueAnnotation(){} 61 62 @Pointcut("bean(simpleSay)") 63 public void beanName(){} 64 65 @Pointcut("bean(*Impl)") 66 public void matchBeanName(){} 67 68}

AnnotationConfigStart

1import org.springframework.context.annotation.AnnotationConfigApplicationContext; 2import org.springframework.context.support.AbstractApplicationContext; 3 4import cn.freemethod.business.HaveResultBusiness; 5import cn.freemethod.business.pack.Say; 6import cn.freemethod.config.AspectConfig; 7 8public class AnnotationConfigStart { 9 10 public static void main(String[] args) { 11 AbstractApplicationContext context = new AnnotationConfigApplicationContext(AspectConfig.class); 12 HaveResultBusiness haveResultBusiness = context.getBean(HaveResultBusiness.class); 13 haveResultBusiness.getResult(100); 14 Say say = context.getBean(Say.class); 15 say.sayChiness("tim"); 16 say.sayEnglish("tim"); 17 say.whatSay(); 18 context.close(); 19 } 20 21}

PointcutExpressionStart

1import org.springframework.context.annotation.AnnotationConfigApplicationContext; 2import org.springframework.context.support.AbstractApplicationContext; 3 4import cn.freemethod.bean.ParamBean; 5import cn.freemethod.business.HaveResultBusiness; 6import cn.freemethod.business.pack.IOtherPointcut; 7import cn.freemethod.business.pack.Say; 8import cn.freemethod.config.AspectConfig; 9 10public class PointcutExpressionStart { 11 12 public static void main(String[] args) { 13 AbstractApplicationContext context = new AnnotationConfigApplicationContext(AspectConfig.class); 14 IOtherPointcut iOtherPointcut = context.getBean(IOtherPointcut.class); 15 iOtherPointcut.printInteger(new Integer(10)); 16 iOtherPointcut.withAnotationParam(new ParamBean()); 17 18 HaveResultBusiness haveResultBusiness = context.getBean(HaveResultBusiness.class); 19 haveResultBusiness.getResult(100); 20 21 Say say = context.getBean(Say.class); 22 say.sayChiness("tim"); 23 say.sayEnglish("tim"); 24 say.whatSay(); 25 context.close(); 26 } 27 28}

参考

完整工程代码

Spring AOP 之一:基本概念与流程

Spring AOP 之二:Pointcut注解表达式

Spring AOP 之三:通知(Advice)方法参数

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )