簡介
在Spring AOP概述中咱們重點注意的是AOP的總體流程和Advice,簡化了一些其餘的東西,其中就有一些對靈活應用Spring AOP很重要的知識點,例如Pointcut表達式,下面就介紹一下Spring AOP的Pointcut表達式。java
若是你對Pointcut表達式的做用還不是很瞭解,能夠先看一下Spring AOP概述,也能夠先了解一下匹配規則,後面會有一些具體的例子來幫助理解。git
咱們使用最多的就是execution表示了,下面就從execution表達式開始介紹吧。github
注意:把designators翻譯爲表達式也許不太合適,因此沒必要糾結這個問題,只須要知道在看到Spring AOP中的designators知道對應的是個什麼東西就能夠了。管它是表達式仍是指示器只是一個代稱而已。spring
execution表達式
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
上面的就是execution表達式的格式,execution匹配的就是鏈接點(Joinpoint,通常是方法),看上面的表達式execution是固定的,方法的修飾符是可選的,返回類型是必須的,定義的全限類型也是可選的,名稱是必須的,參數是必須的,這些均可以使用通配符。express
任何的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個基本是等效的。maven
有且只有一個Serializable參數的方法
args(java.io.Serializable)
只要這個參數實現了java.io.Serializable接口就能夠,無論是java.io.Serializable仍是Integer,仍是String均可以。ide
目標(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中的全部方法。this
bean名字能匹配
bean(*Impl)
bean名字匹配*Impl的bean中的全部方法。.net
實例
這個實例是對Spring AOP概述中介紹的實例進行了擴展。固然下面給的實例也能夠獨立測試,最好是一個一個測試觀察輸出了驗證,多個輸出結果不夠直觀。
下面的圖片是項目工程目錄結構:
下面的代碼列表由於比較多,能夠在後面找到完整的代碼工程代碼的附件連接,由於其餘一些緣由沒有放到github或者碼雲上,能夠直接下載附件解壓使用maven方式導入。
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(){} }
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(); } }