@AspectJ切点函数详解

相关文章链接:

Spring AOP原理详解及实例

观前提示:

本文所使用的IDEA版本为ultimate 2019.1,JDK版本为1.8.0_141,Tomcat版本为9.0.12。

类别 函数 入参 说明
方法切点函数 execution() 方法匹配模式串 满足某一匹配模式的所有目标类方法连接点
方法切点函数 @annotation() 方法注解类名 标注了特定注解的目标方法连接点
方法入参切点函数 args() 类名 定位于入参为特定类型的方法的连接点
方法入参切点函数 @args() 类型注解类名 定位于被特定注解所标注入参的方法的连接点
目标类切点函数 within() 类名匹配串 定位于特定作用域下的所有连接点
目标类切点函数 target() 类名 定位于指定类及其子类
目标类切点函数 @within() 类型注解类名 定位与标注了特定注解的类及其实现类
目标类切点函数 @target() 类型注解类名 定位于标注了特定注解的目标类里所有方法
代理类切点函数 this() 类名 代理类按类型匹配与指定类,则被代理的目标类的所有连接点都匹配与该切点

1 方法切点函数

1.1 execution()

语法表达式如下:

execution(<修饰符模式>?<返回类型模式><方法名模式>(<参数模式>)<异常模式>?)

其中:返回类型模式、方法名模式、参数模式是必选项

1.1.1 通过方法签名定义切点

execution(public * *(..)) 

匹配所有目标类的public方法。第一个 * 代表任意返回类型,第二个 * 代表方法名,而 . . 代表任意入参的方法。

execution(public String *(..))

匹配所有目标类修饰符为public,返回参数类型为String的方法。第一个 * 代表方法名,而 . . 代表任意入参的方法。

1.1.2 通过类定义切点

execution(* com.example.UserService.*(..))

匹配com.example.UserService接口中所有方法。第一个 * 代表任意返回类型,第二个 * 代表com.example.UserService中的所有方法,. . 代表任意入参的方法。

1.1.3 通过类包定义切点

execution(* com.example.*(..))

匹配com.example包下的所有方法。

execution(* com..*(..))

匹配com包及子孙包下所有方法。

类名模式 说明
.* 包中所有的类,不包括子孙包下的类
. .* 包及子孙包下所有的类

1.1.4 通过方法入参定义切点

execution(* com.example.UserService.insert(String,int))

匹配com.example.UserService包下的insert(String,int)方法。

execution(* com.example.UserService.insert(String, *))

匹配com.example.UserService包下的insert()方法,其中第一个参数类型为String,第二个参数类型为任意参数类型。

execution(* com.example.UserService.insert(String,..))

匹配com.example.UserService包下的insert()方法,其中第一个参数类型为String,后面的参数类型为任意类型且个数不限。

execution(* com.example.UserService.insert(Object+))

匹配com.example.UserService包下的insert()方法,方法只有一个入参,为Object类型或Object类型的子类。

类名模式 说明
* 表示任意类型的参数
. . 表示任意个数任意类型的参数

1.1.5 例子

这里给出的例子为通过类定义切点,其他定义切点方式可修改LogAop.java中的注解@Pointcut("execution(* testAop.UserService.*(..))")即可

目录结构
在这里插入图片描述
applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

    <bean id="userService" class="testExecution.UserService"/>
    <!-- 配置自动扫描的包 -->
    <context:component-scan base-package="testExecution"></context:component-scan>
    <!-- 开启aop注解方式,此步骤不能少,这样java类中的aop注解才会生效 -->
    <aop:aspectj-autoproxy/>
</beans>

UserService.java

package testExecution;

public class UserService {
   

    public void insertUser() {
   
        System.out.println("插入用户成功");
    }

    public boolean updateUser() {
   
        System.out.println("更新用户成功");
        return true;
    }
}

LogAop.java

package testExecution;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class LogAop {
   

    @Pointcut("execution(* testExecution.UserService.*(..))")
    public void ponitCut() {
   

    }

    @Before("ponitCut()")
    public void beforeAdvice() {
   
        System.out.println("beforeAdvice");
    }

    @After("ponitCut()")
    public void afterAdvice() {
   
        System.out.println("afterAdvice");
    }

    //环绕通知。注意要有ProceedingJoinPoint参数传入
    @Around("ponitCut()")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
   
        System.out.println("注解类型环绕通知..环绕前");
        pjp.proceed();//执行方法
        System.out.println("注解类型环绕通知..环绕后");
    }
}

TestAop.java

package testExecution;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestAop {
   

    private ClassPathXmlApplicationContext ac;

    @Before
    public void before() {
   
        ac = new ClassPathXmlApplicationContext("testExecution/applicationContext.xml");
    }

    @Test
    public void test() {
   
        try {
   
            UserService userService = (UserService) ac.getBean("userService");
            userService.insertUser();
        } catch (Exception e) {
   
            e.printStackTrace();
        }
    }
}

运行结果

在这里插入图片描述

1.2 @annotation()

用于标注了某个注解的目标切点。

1.2.1 例子

目录结构如下:
在这里插入图片描述

自定义注解 SystemLog.java

package testAnnotation;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME) //注解保留期限
@Target(ElementType.METHOD) //注解目标类型
@Documented
public @interface SystemLog {
   
    int LogType() default Constants.LogType.Empty;
}

注:@Rentention,@Target,@Document注解描述可参考文章:java元注解

常量类Constants.java

package testAnnotation;

public class Constants {
   

    public static class LogType {
   
        public static final int Empty = 0;//默认为0
        public static final int Insert = 1;//插入操作日志
        public static final int Update = 2;//更新操作日志
    }
}

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

    <bean id="userService" class="testAnnotation.UserService"/>
    <!-- 配置自动扫描的包 -->
    <context:component-scan base-package="testAnnotation"></context:component-scan>
    <!-- 开启aop注解方式,此步骤不能少,这样java类中的aop注解才会生效 -->
    <aop:aspectj-autoproxy/>
</beans>

UserService.java

package testAnnotation;

public class UserService {
   

    @SystemLog
    public void defaultMethod(String param){
   
        System.out.println("默认方法,入参为:" + param);
    }

    @SystemLog(LogType = Constants.LogType.Insert)
    public void insertUser() {
   
        System.out.println("插入用户成功");
    }

    @SystemLog(LogType = Constants.LogType.Update)
    public boolean updateUser() {
   
        System.out.println("更新用户成功");
        return true;
    }
}

LogAop.java

package testAnnotation;

import com.alibaba.fastjson.JSON;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation
  • 10
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值