探祕Spring AOP
/** * 匹配WithinService類裏頭的全部方法 * @Pointcut("within(cn.evchar.aop.within.WithinService)") * 匹配com.imooc包及子包下全部類的方法 * @Pointcut("within(cn.evchar.aop.within..*)") */ @Aspect @Component public class WithinAspectConfig { @Pointcut("within(cn.evchar.aop.within..*)") public void matchType(){ } @Before("matchType()") public void before(){ // 編寫須要 織入 System.out.println(""); System.out.println("### before 開始織入邏輯"); } }
/** * * //匹配AOP對象的目標對象爲指定類型的方法,即LogService的aop代理對象的方法 * @Pointcut("this(cn.evchar.aop.target.Loggable)") * * //匹配實現Loggable接口的目標對象(而不是aop代理後的對象)的方法 * @Pointcut("target(cn.evchar.aop.target.Loggable)") * * //this 能夠攔截 DeclareParents(Introduction) * //target 不攔截 DeclareParents(Introduction) * * //匹配全部以Service結尾的bean裏頭的方法 * */ @Aspect @Component public class ObjectAspectConfig { @Pointcut("bean(logService)") public void matchCondition(){} // @Pointcut("this(cn.evchar.aop.target.Loggable)") // public void matchCondition(){} // @Pointcut("target(cn.evchar.aop.target.Loggable)") // public void matchCondition(){} @Before("matchCondition()") public void before(){ System.out.println(""); System.out.println("### before "); } }
/** * * //匹配任何以find開頭並且只有一個Long參數的方法 * @Pointcut("execution(* *..find*(Long))") * //匹配任何以find開頭的並且第一個參數爲Long型的方法 * @Pointcut("execution(* *..find*(Long,..))") * //匹配任何只有一個Long參數的方法 * @Pointcut("within(cn.evchar.aop.service.*) && args(Long)") * //匹配第一個參數爲Long型的方法 * @Pointcut("within(cn.evchar.aop.service.*) && args(Long,..)") * */ @Aspect @Component public class ArgAspectConfig { // 匹配一個參數 @Pointcut("args(Long) && within(cn.evchar.aop.service.*)") public void matchArgs(){} // 匹配,兩個參數,第二個爲任意參數 // @Pointcut("args(Long,..) && within(cn.evchar.aop.service.*)") // public void matchArgs(){} // 匹配,兩個具體類型參數 // @Pointcut("args(Long,String) && within(cn.evchar.aop.service.*)") // public void matchArgs(){} @Before("matchArgs()") public void beforeArgs(){ System.out.println(""); System.out.println("#### before"); } }
/** * //匹配方法標註有AdminOnly的註解的方法 * @Pointcut("@annotation(cn.evchar.aop.anno.AdminOnly) && within(cn.evchar.aop..*)") * //匹配標註有NeedSecured的類底下的方法 //class級別 * @Pointcut("@within(cn.evchar.aop.anno.NeedSecured) && within(cn.evchar.aop..*)") * //匹配標註有NeedSecured的類及其子類的方法 //runtime級別 * 在spring context的環境下,兩者沒有區別 * @Pointcut("@target(cn.evchar.aop.anno.NeedSecured) && within(cn.evchar.aop..*)") * //匹配傳入的參數類標註有Repository註解的方法 * @Pointcut("@args(cn.evchar.aop.anno.NeedSecured) && within(cn.evchar.aop..*)") * */ @Aspect @Component public class AnnoAspectConfig { // 方法上面註解 // @Pointcut("@annotation(cn.evchar.aop.anno.AdminOnly)") // public void matchAnno(){} // 類上面註解 // @Pointcut("@within(cn.evchar.aop.anno.NeedSecured) && within(cn.evchar.aop..*)") // public void matchAnno(){} // 類上面註解 @Pointcut("@target(cn.evchar.aop.anno.NeedSecured) && within(cn.evchar.aop..*)") public void matchAnno(){} // 參數上面註解 // @Pointcut("@args(cn.evchar.aop.anno.NeedSecured) && within(cn.evchar.aop..*)") // public void matchAnno(){} @Before("matchAnno()") public void before(){ System.out.println(""); System.out.println("### before annotation "); } }
標註 ? 部分,能夠省略 ,其他必須存在。java
execution(spring
modifier-pattern? 修飾符部分 例如 public private...this
ret-type-pattern 返回值部分 例如 return String;.net
declaring-type-pattern? 描述包名 例如 cn.evchar....代理
name-pattern(param-pattern) 描述方法名,描述方法參數code
throws-pattern? 匹配拋出的異常對象
)接口
/** * * 匹配任何公共方法 * @Pointcut("execution(public * cn.evchar.aop.service.*.*(..))") * * 匹配com.imooc包及子包下Service類中無參方法 * @Pointcut("execution(* cn.evchar.aop..*Service.*())") * * 匹配com.imooc包及子包下Service類中的任何只有一個參數的方法 * @Pointcut("execution(* cn.evchar.aop..*Service.*(*))") * * 匹配com.imooc包及子包下任何類的任何方法 * @Pointcut("execution(* cn.evchar.aop..*.*(..))") * * 匹配com.imooc包及子包下返回值爲String的任何方法 * @Pointcut("execution(String cn.evchar.aop..*.*(..))") * * 匹配異常 * execution(public * cn.evchar.aop.service.*.*(..) throws java.lang.IllegalAccessException) * */ @Aspect @Component public class ExecutionAspectConfig { // 掃描包下面的類,不包括子包 // @Pointcut("execution(public * cn.evchar.aop.service.*Service.*(..))") // public void matchExecution(){} // 掃描包下面的全部類,包括子包 // @Pointcut("execution(public * cn.evchar.aop.service..*Service.*(..))") // public void matchExecution(){} // 攔截返回是String 類型 // @Pointcut("execution(public String cn.evchar.aop.service..*Service.*(..))") // public void matchExecution(){} // 攔截返回是void // @Pointcut("execution(public String cn.evchar.aop.service..*Service.*(..))") // public void matchExecution(){} // 返回無參 // @Pointcut("execution(public String cn.evchar.aop.service..*Service.*())") // public void matchExecution(){} // 返回第一個參數Long 類型的 // @Pointcut("execution(public String cn.evchar.aop.service..*Service.*(Long))") // public void matchExecution(){} @Pointcut("execution(public String cn.evchar.aop.service..*Service.*(..) " + "throws java.lang.IllegalAccessException)") public void matchExecution(){} @Before("matchExecution()") public void before(){ System.out.println(""); System.out.println("#### before"); } }