Spring基于AspectJ的AOP开发 #yyds干货盘点#

2021年11月24日 阅读数:1
这篇文章主要向大家介绍Spring基于AspectJ的AOP开发 #yyds干货盘点#,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

第一步:添加Maven依赖

<!--AOP相关-->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>${aspectjrt.version}</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjtools</artifactId>
    <version>${aspectjrt.version}</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>${aspectjrt.version}</version>
</dependency>
<dependency>
    <groupId>aopalliance</groupId>
    <artifactId>aopalliance</artifactId>
    <version>${aopalliance.version}</version>
</dependency>

第二步:建立待加强的接口及实现类

Calculator.java

public interface Calculator {
    int add(int a, int b);
    int sub(int a, int b);
    int div(int a, int b);
    int mut(int a, int b);
}

CalculatorImpl.java

@Component("calculator")
public class CalculatorImpl implements Calculator {
    @Override
    public int add(int a, int b) {
        return a + b;
    }

    @Override
    public int sub(int a, int b) {
        return a - b;
    }

    @Override
    public int div(int a, int b) {
        return a / b;
    }

    @Override
    public int mut(int a, int b) {
        return a * b;
    }
}

第三步:切面

@Component  //为切面加入Spring自动扫描支持
@Aspect  //加入AspectJ支持,声明类为切面
public class LogAspect {
    //前置加强
    @Before("execution(public int com.hc.Calculator.*(int,int))")
    public void beforeMethod() {
        System.out.println("前置加强");
    }

    //后置加强
    @After("execution(public int com.hc.Calculator.*(int,int))")
    public void afterMethod(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.print(methodName + " " + Arrays.toString(args));
        System.out.println("   后置加强");
    }

    //返回加强
    @AfterReturning(value = "execution(public int com.hc.Calculator.*(int,int))",
            returning = "result")
    public void afterReturningMethod(JoinPoint joinPoint, int result) {
        String methodName = joinPoint.getSignature().getName(); //获取方法名
        Object[] args = joinPoint.getArgs(); //获取参数列表
        System.out.print(methodName + " " + Arrays.toString(args) + " " + result);
        System.out.println("   返回加强");
    }

    //异常加强
    @AfterThrowing(value = "execution(public int com.hc.Calculator.*(int,int))",
            throwing = "ex")
    public void afterThrowingMethod(JoinPoint joinPoint, ArithmeticException ex) { //---①
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.print(methodName + " " + Arrays.toString(args) + " " + ex);
        System.out.println("   异常加强");
    }

    //环绕加强
    @Around(value = "execution(public int com.hc.Calculator.*(int,int))")
    public Object AroundMethod(ProceedingJoinPoint pjp) {
        Object res = null;
        try {
            System.out.println("环绕加强--前置");
            res = pjp.proceed();//调用目标方法
            System.out.println("环绕加强--返回" + res);
        } catch (Throwable throwable) {
            System.out.println("环绕加强--异常");
            throw new RuntimeException(throwable);  //-----③
        }
        System.out.println("环绕加强--后置");
        return res;
    }
}

切面能够简写为:java

@Component  //为切面加入Spring自动扫描支持
@Aspect  //加入AspectJ支持,声明类为切面
public class LogAspect {
    //切入点
    @Pointcut("execution(public int com.hc.Calculator.*(int,int))")
    public void logPointcut() {
    }
    //前置加强
    @Before("logPointcut()")
    public void beforeMethod() {
        System.out.println("前置加强");
    }
    //后置加强
    @After("logPointcut()")
    public void afterMethod(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.print(methodName + " " + Arrays.toString(args));
        System.out.println("   后置加强");
    }
    //返回加强
    @AfterReturning(pointcut = "logPointcut()", returning = "result")
    public void afterReturningMethod(JoinPoint joinPoint, int result) {
        String methodName = joinPoint.getSignature().getName(); //获取方法名
        Object[] args = joinPoint.getArgs(); //获取参数列表
        System.out.print(methodName + " " + Arrays.toString(args) + " " + result);
        System.out.println("   返回加强");
    }
    //异常加强
    @AfterThrowing(pointcut = "logPointcut()", throwing = "ex")
    public void afterThrowingMethod(JoinPoint joinPoint, ArithmeticException ex) { //---①
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.print(methodName + " " + Arrays.toString(args) + " " + ex);
        System.out.println("   异常加强");
    }
    //环绕加强
    @Around("logPointcut()")
    public Object AroundMethod(ProceedingJoinPoint pjp) {
        Object res = null;
        String methodName = pjp.getSignature().getName();
        Object[] args = pjp.getArgs();
        try {
            System.out.println("环绕加强--前置");
            res = pjp.proceed();//调用目标方法
            System.out.println("环绕加强--返回" + res);
        } catch (Throwable throwable) {
            System.out.println("环绕加强--异常");
            throw new RuntimeException(throwable);  //-----③
        }
        System.out.println("环绕加强--后置");
        return res;
    }
}

第四步:测试

@ExtendWith(SpringExtension.class)
@ContextConfiguration("/applicationContext.xml")
public class AOPTest {
    @Resource
    private Calculator calculator;

    @Test
    void fun1(){
        int addRes = calculator.add(3, 5);
        System.out.println(addRes);
    }

    @Test
    void fun2(){
        int divRes = calculator.div(3,0);
        System.out.println(divRes);
    }
}