简介
在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}