欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于注解的Spring的AOP功能演示

程序员文章站 2022-03-26 16:45:25
我们知道,IOC功能,我们引入以下坐标即可 org.springframework spring-context 5.3.1...

我们知道,IOC功能,我们引入以下坐标即可

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.1</version>
        </dependency>
    </dependencies>

但是AOP功能,需要再引入另一个坐标

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.3.1</version>
        </dependency>
    </dependencies>

首先,定义一个普通的类。

package fun.gosuncn;

import org.springframework.stereotype.Component;

@Component
public class Calculator {

    public int plus(int a, int b) {
        int result = a + b;
        return result;
    }

    public int division(int a, int b) {
        int result = a / b;
        return result;
    }

}

计算器类,实现加法除法的功能。

定义一个切面类:

package fun.gosuncn;

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

@Aspect
@Component
public class CalculatorAspect {

    @Pointcut("execution(* fun.gosuncn.Calculator.*(..))")
    public void pointcut() {
    }

    @Before(value = "pointcut()")
    public void before(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        String method = signature.getName();//获取方法名
        System.out.println(method + "方法{" + signature.toLongString()/*获取方法全类名*/ + "}开始执行");
        Object[] args = joinPoint.getArgs();
        for (int i = 0; i < args.length; i++) {
            System.out.print("\t第" + (i + 1) + "个参数 = " + args[i]);
        }
        System.out.println("\n------------共计" + args.length + "个参数------------");
    }

    @AfterReturning(value = "pointcut()", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        Signature signature = joinPoint.getSignature();
        String method = signature.getName();//获取方法名
        System.out.println(method + "方法{" + signature.toLongString()/*获取方法全类名*/ + "}执行正常");
        System.out.println("\t返回结果 = " + result);
    }

    @AfterThrowing(value = "pointcut()", throwing = "throwable")
    public void afterThrowing(JoinPoint joinPoint, Throwable throwable) {
        Signature signature = joinPoint.getSignature();
        String method = signature.getName();//获取方法名
        System.out.println(method + "方法{" + signature.toLongString()/*获取方法全类名*/ + "}发生异常");
        System.out.println("\t异常信息 = " + throwable.getMessage());
    }

    @After(value = "pointcut()")
    public void after(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        String method = signature.getName();//获取方法名
        System.out.println(method + "方法{" + signature.toLongString()/*获取方法全类名*/ + "}执行完毕");
    }

    /**
     * 建议:如果使用了 @Around ,就不用再写[@Before、@AfterReturning、@AfterThrowing、@After]了。
     */
    @Around(value = "pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Signature signature = joinPoint.getSignature();
        String method = signature.getName();//获取方法名
        System.out.println(method + "方法{" + signature.toLongString()/*获取方法全类名*/ + "}环绕前");
        //参数列表
        Object[] args = joinPoint.getArgs();
        Object result = joinPoint.proceed(args);
        System.out.println(method + "方法{" + signature.toLongString()/*获取方法全类名*/ + "}环绕后\n\n");
        return result;
    }

}

加法除法执行时,进行操作。

接下来,进行Spring配置:

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:component-scan base-package="fun.gosuncn"/>

    <!--使用注解方式必须加上-->
    <!--开启基于注解的AOP功能-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

简单,解释一下:

<context:component-scan base-package="fun.gosuncn"/>这句话,说了要通过注解的方式导入组件。

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>这句话,说了要通过注解的方式使用AOP功能。要想使用注解,必须写这一项!不然,没用,我试过了,^v^.

完事了,就运行吧!

package fun.gosuncn;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AopMain {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        Calculator calculator = applicationContext.getBean("calculator", Calculator.class);
        int plus = calculator.plus(2, 3);
        int division = calculator.division(2, 1);
    }
}

执行结果:

plus方法{public int fun.gosuncn.Calculator.plus(int,int)}环绕前
plus方法{public int fun.gosuncn.Calculator.plus(int,int)}开始执行
第1个参数 = 2 第2个参数 = 3
------------共计2个参数------------
plus方法{public int fun.gosuncn.Calculator.plus(int,int)}执行正常
返回结果 = 5
plus方法{public int fun.gosuncn.Calculator.plus(int,int)}执行完毕
plus方法{public int fun.gosuncn.Calculator.plus(int,int)}环绕后
division方法{public int fun.gosuncn.Calculator.division(int,int)}环绕前
division方法{public int fun.gosuncn.Calculator.division(int,int)}开始执行
第1个参数 = 2 第2个参数 = 1
------------共计2个参数------------
division方法{public int fun.gosuncn.Calculator.division(int,int)}执行正常
返回结果 = 2
division方法{public int fun.gosuncn.Calculator.division(int,int)}执行完毕
division方法{public int fun.gosuncn.Calculator.division(int,int)}环绕后

假设,我们来个除0异常试试来

public class AopMain {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        Calculator calculator = applicationContext.getBean("calculator", Calculator.class);
        int plus = calculator.plus(2, 3);
        int division = calculator.division(2, 0);
    }
}

int division = calculator.division(2, 0);看到没?2/0=?,来吧,展示

plus方法{public int fun.gosuncn.Calculator.plus(int,int)}环绕前
plus方法{public int fun.gosuncn.Calculator.plus(int,int)}开始执行
第1个参数 = 2 第2个参数 = 3
------------共计2个参数------------
plus方法{public int fun.gosuncn.Calculator.plus(int,int)}执行正常
返回结果 = 5
plus方法{public int fun.gosuncn.Calculator.plus(int,int)}执行完毕
plus方法{public int fun.gosuncn.Calculator.plus(int,int)}环绕后
division方法{public int fun.gosuncn.Calculator.division(int,int)}环绕前
division方法{public int fun.gosuncn.Calculator.division(int,int)}开始执行
第1个参数 = 2 第2个参数 = 0
------------共计2个参数------------
division方法{public int fun.gosuncn.Calculator.division(int,int)}发生异常
异常信息 = / by zero
division方法{public int fun.gosuncn.Calculator.division(int,int)}执行完毕
Exception in thread “main” java.lang.ArithmeticException: / by zero
at fun.gosuncn.Calculator.division(Calculator.java:14)
at fun.gosuncn.Calculator$$FastClassBySpringCGLIB$$d9da4f70.invoke()
…太长了
…不写了
at fun.gosuncn.AopMain.main(AopMain.java:10)

本文地址:https://blog.csdn.net/ApolloNing/article/details/110262052

相关标签: spring aop