前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring AOP基础运用

Spring AOP基础运用

作者头像
长安不见使人愁
发布2022-10-25 19:24:52
2080
发布2022-10-25 19:24:52
举报
文章被收录于专栏:给时光以生命

模拟计算器的加减乘除,在每次调用方法前后进行模拟日志输出。

  • 配置自动扫包 和 自动完成创建代理织入切面 spring.xml
代码语言:javascript
复制
<context:component-scan base-package="per.tan"/>
<aop:aspectj-autoproxy/>
  • 原始业务接口 Calc
代码语言:javascript
复制
public interface Calc {
    Integer add(Integer num1, Integer num2);
    Integer min(Integer num1, Integer num2);
    Integer mul(Integer num1, Integer num2);
    Integer div(Integer num1, Integer num2);
}
  • 原始业务实现类 CalcImpl
代码语言:javascript
复制
@Component
public class CalcImpl implements Calc {

    @Override
    public Integer add(Integer num1, Integer num2) {
        Integer result = num1 + num2;
        System.out.println("执行业务,完成了一次加法!");
        return result;
    }

    @Override
    public Integer min(Integer num1, Integer num2) {
        Integer result = num1 - num2;
        System.out.println("执行业务,完成了一次减法!");
        return result;
    }

    @Override
    public Integer mul(Integer num1, Integer num2) {
        Integer result = num1 * num2;
        System.out.println("执行业务,完成了一次乘法!");
        return result;
    }

    @Override
    public Integer div(Integer num1, Integer num2) {
        Integer result = num1 / num2;
        System.out.println("执行业务,完成了一次除法!");
        return result;
    }
}
  • 切面类 LogAspect
代码语言:javascript
复制
@Component
@Aspect
public class LogAspect {
    //指定位置,方法通配符 * ,参数通配符 .. 。
    @Before(value = "execution(public Integer per.tan.aop.CalcImpl.*(..))")
    public void before(JoinPoint joinPoint) {
        String name = joinPoint.getSignature().getName();
        String args = Arrays.toString(joinPoint.getArgs());
        System.out.println(name + "之前记录日志[Before]" + ",参数为:" + args);
    }

    @After(value = "execution(public Integer per.tan.aop.CalcImpl.*(..))")
    public void after(JoinPoint joinPoint) {
        String name = joinPoint.getSignature().getName();
        System.out.println(name + "之后记录日志[After]");
    }

    @AfterReturning(value = "execution(public Integer per.tan.aop.CalcImpl.*(..))", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        String name = joinPoint.getSignature().getName();
        System.out.println(name + "之后记录日志[AfterReturning],并拿到返回值:" + result);
    }

    @AfterThrowing(value = "execution(public Integer per.tan.aop.CalcImpl.*(..))", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Exception e) {
        String name = joinPoint.getSignature().getName();
        System.out.println(name + "之后记录日志[afterThrowing],异常信息为:" + e);
    }
}
  • 测试 Test
代码语言:javascript
复制
public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Calc calc = context.getBean(Calc.class);
        calc.add(10, 2);
        System.out.println();
        calc.min(10, 2);
        System.out.println();
        calc.min(10, 2);
        System.out.println();
        calc.div(10, 2);
        System.out.println();
        calc.div(10, 0);
    }
}
  • 测试结果
代码语言:javascript
复制
D:\Java_JDK\JDK8\bin\java.exe ...
五月 16, 2021 4:19:15 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7daf6ecc: startup date [Sun May 16 16:19:15 CST 2021]; root of context hierarchy
五月 16, 2021 4:19:15 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring.xml]
add之前记录日志[Before],参数为:[10, 2]
执行业务,完成了一次加法!
add之后记录日志[After]
add之后记录日志[AfterReturning],并拿到返回值:12

min之前记录日志[Before],参数为:[10, 2]
执行业务,完成了一次减法!
min之后记录日志[After]
min之后记录日志[AfterReturning],并拿到返回值:8

min之前记录日志[Before],参数为:[10, 2]
执行业务,完成了一次减法!
min之后记录日志[After]
min之后记录日志[AfterReturning],并拿到返回值:8

div之前记录日志[Before],参数为:[10, 2]
执行业务,完成了一次除法!
div之后记录日志[After]
div之后记录日志[AfterReturning],并拿到返回值:5

div之前记录日志[Before],参数为:[10, 0]
div之后记录日志[After]
div之后记录日志[afterThrowing],异常信息为:java.lang.ArithmeticException: / by zero
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at per.tan.aop.CalcImpl.div(CalcImpl.java:36)
  • 相关概念
    • 切面对象:根据切面抽象出来的对象,CalcImpl中所有方法中需要加入日志的部分,抽象成一个切面类LogAspect。
    • 通知:切面对象具体执行的代码,即非业务代码,LogAspect对象打印日志的代码。
    • 目标:被横切的对象,即CalcImpl,将通知加入其中。
    • 代理:切面对象,通知,目标混合之后的结果,即使用JDK动态代理机制创建的对象。
    • 连接点:需要被横切的位置,即通知要插入业务代码的具体位置。

Q.E.D.

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 模拟计算器的加减乘除,在每次调用方法前后进行模拟日志输出。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档