探秘Spring AOP (四) Spring AOP 使用讲解 3

探秘Spring AOP

  • designators 指示器包括以下:

1、匹配包、类型 within

/**
 * 匹配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 开始织入逻辑");
    }
}

2、匹配对象 bean, this, target

/**
 *
 * //匹配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 ");
    }
}

3、匹配参数 Args

/**
 *
 * //匹配任何以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");
    }
}

4、匹配注解 anno @annotation@within@target@args

/**
 * //匹配方法标注有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 ");
    }

}

5、匹配方法 execution

标注 ? 部分,能够省略 ,其他必须存在。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");
    }
}
相关文章
相关标签/搜索