前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >AOP能干什么?

AOP能干什么?

作者头像
小王不头秃
发布2024-06-19 17:41:18
1730
发布2024-06-19 17:41:18
举报

AOP能干什么?

我们在之前的博客中已经提出了一个例子,可以通过AOP来实现权限的一个认证,详情可以参考这篇博客 AOP是什么

总所周知哈,AOP可以在不改变原代码的情况下完成一些我们意想不到操作,那么到底可以用来干什么呢?咱们一起来看一看

预备知识

首先,咱们要先了解一些小知识点,首先什么是Advice?

例如,我们设计了一个验证码校对接口,因为我们并不需要区别大小写,所以我们要把输入的字母全都调整为大写,但是我们并不想在接口内部对字母进项大写操作,因此我们在接口前建立一个切面,把所有的字母都调整为大写,把字母调整为大写的操作就是Advice

Advice的类别有以下几类,为了方便理解,我们以接口为例介绍Advice的类别。

Before Advice

可以理解为进入接口之前的操作,也就是刚刚我们提到的字母进入接口之前,先用我们的Advice把它调成大写,举个栗子

Aspect Aspect就是point cut 与 Advice的组合

代码语言:javascript
复制
package com.xiaow.springsecuriydemo.aop.advice;

import com.xiaow.springsecuriydemo.entity.Admin;
import com.xiaow.springsecuriydemo.entity.Person;
import com.xiaow.springsecuriydemo.service.AdminService;
import com.xiaow.springsecuriydemo.service.PersonService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Array;
import java.util.List;

@Aspect
@Component
public class TestAdvice {
     //Pointcut
    @Pointcut("@annotation(com.xiaow.springsecuriydemo.aop.annotation.TestAnnotation)")
    public void TestPointCut() {

    }
    //Advice
    @Before(value = "TestPointCut()")
    public void before(JoinPoint joinPoint) throws IllegalAccessException, NoSuchFieldException {
        System.out.println("Advice");
    }


}

Controller

代码语言:javascript
复制
@GetMapping("testAOP")
    @TestAnnotation
    public Result testAOP(@RequestParam(required = false) String info) {
        System.out.println("接口处理");
        return Result.succ(info);
    }

调用接口之后可以发现,先进行的Before Advice然后执行接口内的操作

After Advice

接口执行完毕之后执行的Advice,无论接口内操作正常结束还是抛出异常,都会执行的内容

把注解改一下就可以,由Before改为了After

代码语言:javascript
复制
@After(value = "TestPointCut()")
    public void before(JoinPoint joinPoint) throws IllegalAccessException, NoSuchFieldException {
        System.out.println("Advice");
    }

看下结果

确实Advice是在接口之后执行的,那么咱们看看有异常了还能执行吗

改下接口,经典的1/0

代码语言:javascript
复制
@GetMapping("testAOP")
    @TestAnnotation
    public Result testAOP(@RequestParam(required = false) String info) {
        System.out.println("接口处理");
        int a=1/0;
        return Result.succ(info);
    }

看下结果

虽然一堆异常,但很明显还是执行了

Around Advice

这个我认为是最自由的Advice了。Around,顾名思义,环绕的意思,就是说进入接口前和出接口后,都可以操作,那么我们想要修改参数值,返回值之类的就很方便了。这里举个例子。

修改下Advice

代码语言:javascript
复制
@Around(value = "TestPointCut()")
    public void before(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Before");
        Object[] args = joinPoint.getArgs();
        Object proceed = joinPoint.proceed(args);
        System.out.println("After");
    }

输出结果如下

可以注意到,此时若是接口中出现异常,并不能返回输出After。

那怎么次啊能无视异常,直接输出After呢?

这时候,你就突然想到了,这里不进行下面操作了是因为我们把异常抛出去了,那我们直接不抛不就完事了

代码语言:javascript
复制
    @Around(value = "TestPointCut()")
    public void before(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Before");
        try {
            Object[] args = joinPoint.getArgs();
            Object proceed = joinPoint.proceed(args);
        }catch (Exception e){
         e.printStackTrace();
        }

        System.out.println("After");
    }

输出结果如下,这不就可以了

另外,还有两类,这里博主就不仔细讲了,咱们主要是围绕着Around Advice进行处理,来看看这能有什么用吧

AOP能干啥呢

这里我们从输入参数和返回结果两方面去考虑哈。

例如说,我们在接收到一些参数值时,我们可能需要对其进行处理之后才能使用,并且每个接口都需要做这样的预处理,这时候每个接口都写相同的代码就太冗余了,那是不是可以用AOP进行处理呢,答案是可以的。

另外,我们在返回结果时,也需要对结果处理之后才能返回,同样所有接口都需要做这个操作,这个固定的操作同样也可以用AOP进行处理。

咱们举两个例子来看下怎么搞吧。

处理参数值

ok,还是刚才的例子哈。

假如哈,重点是假如哈。

博主来扮演一个极度自恋的人,即使听到别人说我丑,博主也会自动认为被人再夸博主帅

那我们怎么做呢,是不是把输入的丑字换成帅就可以了,然后帅的话就什么都不管了

那看看咋弄哈

代码语言:javascript
复制
 @GetMapping("testAOP")
    @TestAnnotation
    public Result testAOP(@RequestParam(required = false) String info) {
        return Result.succ(info);
    }

Controller不需要变,就改Aspect就可以,这就是AOP的魅力!

注意哈

代码语言:javascript
复制
Object proceed = joinPoint.proceed(args);

joinPoint.proceed完全可以认为是执行接口函数,也就是proceed就是接口输出的结果,args就是我们传递给接口的参数值,那么就很好改了,那咱们直接改下args就可以了,

代码语言:javascript
复制
@Around(value = "TestPointCut()")
    public Object before(ProceedingJoinPoint joinPoint) throws Throwable {
        Object proceed=null;
        System.out.println("Before");
        try {
        // 获取方法的参数值
            Object[] args = joinPoint.getArgs();
            String info = (String) args[0];
        // 修改传递的参数值
            args[0] = info.replaceAll("丑", "帅");
        // 传递修改的参数值给接口
            proceed = joinPoint.proceed(args);
        }catch (Exception e){
            e.printStackTrace();
        }

        System.out.println("After");
        return proceed;
    }

调用路径

代码语言:javascript
复制
http://localhost:8080/test/testAOP?info=太丑了

输出结果

很对!

处理输出结果

那么咱们怎么更改这个输出结果呢,和上面一样,改一下proceed就可以了,来看看咋改吧

代码语言:javascript
复制
   @Around(value = "TestPointCut()")
    public Object before(ProceedingJoinPoint joinPoint) throws Throwable {
        Object proceed=null;
        System.out.println("Before");
        try {
            Object[] args = joinPoint.getArgs();
            proceed = joinPoint.proceed(args);
        }catch (Exception e){
            e.printStackTrace();
        }
        // 获取原来的结果
        Result result= (Result) proceed;
        // 能到原来结果返回的字符串
        String info = (String) result.getData();
        // 修改该字符串,然后设置给返回结果
        result.setData(info.replaceAll("丑", "帅"));
        System.out.println("After");

        return result;
    }

来看看结果,这就很对了

总结

上面只是开个玩笑,其实Around Advice有很多大用处。

例如,一个接口是基于参数值查询结果,但是并没有设置权限,会导致没有权限的用户传递参数之后获取到不应该让他看到的数据,此时就可以对参数值进行处理,滤除掉不应该被传递过来的参数。

另外,我们在数据库设置1或0表示一种状态,但是前端不能显示0和1啊,这时候就可以通过修改输出结果来给出详细的状态描述,也可以理解为一种字典翻译。

好了,今天的AOP就到这了,溜了溜了

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • AOP能干什么?
  • 预备知识
    • Before Advice
      • After Advice
        • Around Advice
        • AOP能干啥呢
          • 处理参数值
            • 处理输出结果
            • 总结
            相关产品与服务
            验证码
            腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档