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

本文深入探讨了 Spring AOP 的核心概念,详细解释了 designators 指示器的功能,包括 within 匹配包和类型、bean/this/target 匹配对象、Args 匹配参数、anno 匹配注解以及 execution 匹配方法等关键知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

探秘Spring AOP

  • designators 指示器包括如下:

一、匹配包、类型 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 开始织入逻辑");
    }
}

二、匹配对象 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 ");
    }
}

三、匹配参数 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");
    }
}

四、匹配注解 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 ");
    }

}

五、匹配方法 execution

标注 ? 部分,可以省略 ,其余必须存在。

execution(

modifier-pattern? 修饰符部分 例如 public private...

ret-type-pattern 返回值部分 例如 return String;

declaring-type-pattern? 描述包名 例如 cn.evchar....

name-pattern(param-pattern) 描述方法名,描述方法参数

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

转载于:https://my.oschina.net/u/3136594/blog/1555099

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值