探秘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"); } }