栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java > SpringBoot

Spring基础使用(六)-------AOP切面表达式

SpringBoot 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring基础使用(六)-------AOP切面表达式

1. expression表达式

expression表达式分为三部分:指示器,通配符和操作符。

指示器
  • 匹配方法:execution()
  • 匹配注解:@target(),@args(),@within(),@annotation()
  • 匹配包/类型:within()
  • 匹配对象:this(),bean(),target()
  • 匹配参数:args()
通配符
  • *:匹配任意数量的字符
  • +:匹配指定类及其子类
  • ..:匹配任意数量的子包或者参数
运算符
  • &&:与
  • ||:或
  • !:非
2. 示例 匹配方法:execution()

execution()匹配方式使用的较为广泛,其格式如下图所示,其中修饰符和异常可以省略。

    @Pointcut("execution(public * studySpring.service.LearnServiceImpl.get*(..))")
    public void pointCut1(){}

    // 前置通知
    @Before("pointCut1()")
    public void before()
    {
 System.out.println("AspectJDemo|before");
    }
注解匹配:@target(),@args(),@within(),@annotation()

@annotation()可以单独进行使用,其他三种注解,需要指定包或者类。

1. @annotation()匹配标注有指定注解的方法。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation
{
}
    // 使用新注解修饰方法
    @MyAnnotation
    public void learn(String arg)
    {
 System.out.println("enter function learn");
 System.out.println("学习课程:" + arg);
 daoImpl.save(arg);
    }
    // 定义Pointcut,指定注解匹配方法
    @Pointcut("@annotation(studySpring.annotation.MyAnnotation)")
    public void pointCut1(){}

    // 前置通知
    @Before("pointCut1()")
    public void before()
    {
 System.out.println("AspectJDemo|before");
    }
2. @target()和@within()匹配标注有指定注解的类中的方法。
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface TargetWith
    {
    }
    @Component
    @TargetWith
    public class LearnServiceImpl implements ServiceInterface
    {
 ...
    }
    // 定义Pointcut,匹配指定注解的类中的所有方法
    @Pointcut("@target(studySpring.annotation.TargetWith) && within(studySpring.service..*)")
    // @Pointcut("@within(studySpring.annotation.TargetWith) && within(studySpring.service..*)")
    public void pointCut1(){}

    // 前置通知
    @Before("pointCut1()")
    public void before()
    {
 System.out.println("AspectJDemo|before");
    }
3. 当使用@args()注解修饰类的时候,对于只用该类作为参数的方法,被拦截。
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface TargetWith
    {
    }
    @Component
    @MyArgsAnnotation
    public class Item
    {
 public String name;
 public int grade;
 ...
    }
    // 定义Pointcut,匹配注解修饰的类作为参数的方法
    @Pointcut("@args(studySpring.annotation.MyArgsAnnotation) && within(studySpring.service..*)")
    public void pointCut1(){}

    // 前置通知
    @Before("pointCut1()")
    public void before()
    {
 System.out.println("AspectJDemo|before");
    }
匹配包/类型:within()

within主要用于匹配指定的类或者包及其子包下的所有方法。

    // 定义切入点
    @Pointcut("within(studySpring.service.LearnServiceImpl)")
    public void pointCut1(){}

    // 定义切入点
    @Pointcut("within(studySpring.service..*)")
    public void pointCut2(){}

    // 前置通知
    @Before("pointCut1()")
    public void before()
    {
 System.out.println("AspectJDemo|before");
    }

    // 正常返回后通知
    @AfterReturning("pointCut2()")
    public void afterReturning()
    {
 System.out.println("AspectJDemo|afterReturning");
    }
对象匹配:this(),target(),bean()

this() 和 target()
的用法大体相同,主要作用有2点。第一,用于匹配实现指定接口的aop代理类;第二,匹配指定类的aop代理类。

bean() 用于匹配指定名称的bean。

1. 匹配实现指定接口的aop代理类(这里使用target和this都可以)
    // 匹配实现指定接口的aop代理类,这里使用target和this都可以。
    @Pointcut("target(studySpring.interfaces.ServiceInterface)")
    // @Pointcut("this(studySpring.interfaces.ServiceInterface)")
    public void pointCut1(){}

    // 前置通知
    @Before("pointCut1()")
    public void before()
    {
 System.out.println("AspectJDemo|before");
    }
@Component
public class LearnServiceImpl implements ServiceInterface
{
    public void learn(String arg)
    {
 System.out.println("enter function learn");
 System.out.println("学习课程:" + arg);
 daoImpl.save(arg);
    }
}
@Component
public class ShopServiceImpl implements ServiceInterface
{
    public void getList()
    {
 System.out.println("enter function ShopServiceImpl.getList()");
 System.out.println("黑凤梨");
 System.out.println("巧克力");
    }
}
2. 匹配指定类的aop代理类(使用target和this都可以)
    // 匹配指定类的aop代理类,这里使用target和this都可以。
    @Pointcut("target(studySpring.service.LearnServiceImpl)")
    // @Pointcut("this(studySpring.service.LearnServiceImpl)")
    public void pointCut1(){}

    // 前置通知
    @Before("pointCut1()")
    public void before()
    {
 System.out.println("AspectJDemo|before");
    }
3. bean() 用于匹配指定名称的bean
    // 匹配指定名称的bean:匹配名称中包含Service字符串的bean
    @Pointcut("bean(*Service*)")
    public void pointCut1(){}

    // 前置通知
    @Before("pointCut1()")
    public void before()
    {
 System.out.println("AspectJDemo|before");
    }
参数匹配:args()

用于匹配指定参数类型的方法,比如args(String)。

还可以结合通配符使用,匹配第一个参数为String的方法:args(String,..)

但是args的匹配方法存在一个使用限制,无法单独使用,必须指定包或者类,否则程序异常。

    // 匹配第一个参数类型为String,而且在studySpring.service包中的方法。
    @Pointcut("args(String,..) && within(studySpring.service.*)")
    // 匹配参数类型为String,而且名称包含Service字段的bean中的方法。
    // @Pointcut("args(String) && bean(*Service*)")
    public void pointCut1(){}

    // 前置通知
    @Before("pointCut1()")
    public void before()
    {
 System.out.println("AspectJDemo|before");
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/235517.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号