AOP到底是啥

AOP到底是啥

  • 前言
  • 面向切面编程到底是啥意思
  • 那么要怎么实现面向切面编程呢?
  • 成果

前言

回忆起来,第一次听到这三字母是博主在上大二的时候,那时候看的一脸懵逼,现在马上研二了才想起来回顾下。

只记得当时面向对象编程还没整明白,这一下子又来个面向切面编程,这直接给整懵了。。。。
在这里插入图片描述
面向对象相信大家都很了解了,那咱们接下来看看什么是面向切面编程。

面向切面编程到底是啥意思

咱不整哪些官方话术了,整点通俗的。

想象以下这样的一个场景,你接手了一个人员管理系统,这个项目并没有做任何的权限管理,并且大部分功能已经完成,这时候甲方突然来了个新需求,我现在希望你加上对人员管理的权限,即部门经理只能管理其部门的人员,不能管理其他部门的人员。

这时候,你可能想到要不加个安全框架,但很快你就放弃了,因为这种需要给权限的接口实在是太多了,总不能一个个根据用户权限限制管理权限这么去改吧。

这时候aop的作用就出现了
在这里插入图片描述
那可以怎么做呢?

我们通常会将包含接口的Controller都放在一个package中,这时候我们就在想,我们可不可以在职工id传递给接口之前对传递的职工id操作一下呢?

即前端传递过来之后,我们在对这些id再进行一次审核,将没有权限管理的职工id删掉可以不?

很幸运,可以

我们可以认为客户端到调用接口这之间存在一个面,在这个面上我们可以处理将要传递给接口的id参数进行处理,将那些没有权限操作的id直接删除。这个面就可以认为是切面,面向切面编程就是这样。

这里只是一个例子,切面不仅存在这种情况中,对象和对象之间,方法和方法之间等等之间都可以认为是一个切面。

那么要怎么实现面向切面编程呢?

这里我们用注解的方式实现

首先就是我们怎么监视这个面呢?
先看下接口

package com.xiaow.springsecuriydemo.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaow.springsecuriydemo.entity.Person;
import com.xiaow.springsecuriydemo.service.PersonService;
import com.xiaow.springsecuriydemo.vo.Result;
import io.jsonwebtoken.lang.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.Collection;
import java.util.List;/*** <p>* 前端控制器* </p>** @author xiaow* @since 2023-09-01*/
@RestController
@RequestMapping("/person")
public class PersonController {@AutowiredPersonService personService;@GetMapping("getPersons")public Result getPersons(int adminid, int[] personids) {LambdaQueryWrapper<Person> personLambdaQueryWrapper = new LambdaQueryWrapper<>();List list1 = Collections.arrayToList(personids);personLambdaQueryWrapper.in(Person::getId, list1);List<Person> list = personService.list(personLambdaQueryWrapper);return Result.succ(list);}}

这里的mplus操作,就交给大家去写了。

来了解下怎么写Aspect

@Before(value = "execution(* com.xiaow.springsecuriydemo.controller.*.*(..))")

Before也就是在接口执行前,我们对其进行操作,com.xiaow.springsecuriydemo.controller就是我们存放controller的包,后面的第一个*代表任意一个Controller,第二个*() 就是任意的方法

其意义就是在com.xiaow.springsecuriydemo.controller下的所有接口执行前,做一步处理,那么处理什么呢?

当然是处理传递的员工id,就是把那些无权限处理的id替代掉,这里我们使用-1来代替,因为id为-1不会指向任何员工信息。

看下完整的代码

package com.xiaow.springsecuriydemo.aop.advice;import com.xiaow.springsecuriydemo.aop.annotation.ArgsAnnotation;
import com.xiaow.springsecuriydemo.aop.annotation.ArraysAnnotation;
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.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;@Aspect
@Component
public class PersonAdvice {@AutowiredAdminService adminService;@AutowiredPersonService personService;//  在进入接口之前执行@Before(value = "execution(* com.xiaow.springsecuriydemo.controller.*.*(..))")public void before(JoinPoint joinPoint) throws IllegalAccessException, NoSuchFieldException {final Signature signature = joinPoint.getSignature();MethodSignature methodSignature = (MethodSignature) signature;// 获取参数的名字final String[] names = methodSignature.getParameterNames();// 获取参数的值final Object[] args = joinPoint.getArgs();int admin_index = -1;int personid_index = -1;// 获取到adminid和personids的下标位置for (int i = 0; i < names.length; i++) {if (names[i].equals("adminid")) {admin_index = i;}if (names[i].equals("personids")) {personid_index = i;}}Integer adminid = (Integer) args[admin_index];int [] personid = (int[]) args[personid_index];Admin byId = adminService.getById(adminid);if (byId != null) {Integer deptid = byId.getDeptid();List<Person> byDeptIdAndPersonids = personService.getByDeptIdAndPersonids(deptid, personid);int[] personids = (int[]) args[personid_index];for (Integer i = 0; i < personids.length; i++) {boolean flag = false;for (Person byDeptIdAndPersonid : byDeptIdAndPersonids) {if (personids[i] == byDeptIdAndPersonid.getId())flag = true;}
//              若不在有权限的id中,则直接设置为-1if (!flag)Array.setInt(personid, i, -1);}}}// 在接口执行完毕后执行@After(value = "execution(* com.xiaow.springsecuriydemo.controller.*.*(..))")public void after() {System.out.println("after");}}

成果

就这样我们在不修改原有的接口的情况下,实现了权限控制,如下图

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/69610.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TDengine(2):wsl2+ubuntu20.04+TDengine安装

一、ubuntu系统下提供了三种安装TDengine的方式&#xff1a; 二、通过 apt 指令安装失败 因为是linux初学者&#xff0c;对apt 指令较为熟悉&#xff0c;因此首先使用了该方式进行安装。 wget -qO - http://repos.taosdata.com/tdengine.key | sudo apt-key add -echo "…

【Linux】文件

Linux 文件 什么叫文件C语言视角下文件的操作文件的打开与关闭文件的写操作文件的读操作 & cat命令模拟实现 文件操作的系统接口open & closewriteread 文件描述符进程与文件的关系重定向问题Linux下一切皆文件的认识文件缓冲区缓冲区的刷新策略 stuout & stderr 什…

STM32 硬件IIC 控制OLED I2C卡死问题

#更新通知&#xff1a;2023-09-06 STM32L151 固件库 使用I2C 太难了&#xff0c;又宕机了&#xff0c;建议不要在固件库版本上尝试硬件IIC 了&#xff0c;一般人真用不了&#xff0c;直接使用软件模拟的&#xff0c;或者不要使用固件库了&#xff0c;用HAL 库吧&#xff0c;据说…

既要炫酷好看,又要出图快?可视化大屏模板了解下!

可视化大屏模板可以在很大程度上满足炫酷好看和出图快的需求。使用模板可以节约制作时间&#xff0c;像奥威BI系统就上线了大量的可视化大屏模板。这些模板实际上都是一张张完整的可视化大屏报表&#xff0c;从数据源到数据分析模型&#xff0c;再到数据可视化图表和智能分析功…

《vue3实战》运用push()方法实现电影评价系统的添加功能

目录 前言 电影评价系统的添加功能是什么&#xff1f; 电影评价系统的添加功能有什么作用&#xff1f; 一、push&#xff08;&#xff09;方法是什么&#xff1f;它有什么作用&#xff1f; 含义&#xff1a; 作用&#xff1a; 二、功能实现 这段是添加开始时点击按钮使…

支持CAN FD的Kvaser PCIEcan 4xCAN v2编码: 73-30130-01414-5如何应用?

这里是引用 Kvaser PCIEcan 4xCAN v2&#xff08;编码: 73-30130-01414-5&#xff09;是一款小巧而先进的多通道实时CAN接口&#xff0c;可发送和接收CAN总线上的标准和扩展CAN消息&#xff0c;时间戳精度高。其与所有使用Kvaser CANlib的应用程序兼容。 主要特性 PCI Express…

spring boot项目上传头像

应用还是验证码使用的原理&#xff1b;但是代码逻辑却有所不同。 逻辑前端传给后端&#xff0c;然后写入本机磁盘去&#xff0c;文件名用uuid避免重复。写完就可以顺带把文件名保存到数据库里。上传就这样子。 怎么取用的&#xff1b;还是通过配置映射的方式&#xff1b;通过sr…

vue3升级了些什么

Vue 3 升级了以下几个方面的内容&#xff1a; 响应式系统&#xff1a;Vue 3 使用了 Proxy 对象来替代 Vue 2 中的 Object.defineProperty&#xff0c;这使得响应式系统更加高效和灵活。Vue 3 的响应式系统可以追踪更细粒度的依赖关系&#xff0c;提供了更好的性能和更细致的响应…

Bootstrap的行、列布局设计(网络系统设计)

目录 00-基础知识01-等宽列布局02-指定某一列的宽度03-根据内容自动改变列的宽度04-五种预定义列宽度 .col、.col-sm-*、.col-md-*、.col-lg-*、.col-xl-*05-不同视口宽度按不同的分列方案划分06-删除列内容的盒模型的外边距07-超过12列怎么办&#xff1f;08-重新排列各列的顺序…

继承(个人学习笔记黑马学习)

1、基本语法 #include <iostream> using namespace std; #include <string>//普通实现页面//Java页面 //class Java { //public: // void header() { // cout << "首页、公开课、登录、注册...(公共头部)" << endl; // } // void footer() …

【精品】NLP自然语言处理学习路线(知识体系)

当前&#xff0c;大规模预训练语言模型的强大对话问答、文本生成能力&#xff0c;将自然语言处理&#xff08;NLP&#xff09;的研究和应用推向了新一轮的热潮。NLP是计算机科学、人工智能和语言学等学科交叉的前沿领域。NLP的应用和研究范围非常的广泛&#xff0c;个人是没有找…

利用GitHub实现域名跳转

利用GitHub实现域名跳转 一、注册一个 github账号 你需要注册一个 github账号,最好取一个有意义的名字&#xff0c;比如姓名全拼&#xff0c;昵称全拼&#xff0c;如果被占用&#xff0c;可以加上有意义的数字. 本文中假设用户名为 UNIT-wuji(也是我的博客名) 地址: https:/…

Git常用命令用法

参考视频&#xff1a;真的是全能保姆 git、github 保姆级教程入门&#xff0c;工作和协作必备技术&#xff0c;github提交pr - pull request_哔哩哔哩_bilibili 1.Git初始化 首先设置名称和邮箱。然后初始化一下&#xff0c;然后就创建了一个空的Git仓库。 PS D:\golang\oth…

node socket.io

装包&#xff1a; yarn add socket.io node后台&#xff1a; const express require(express) const http require(http) const socket require(socket.io) const { getUserInfoByToken } require(../../utils/light/tools)let app express() const server http.createS…

【C++漂流记】结构体的定义和使用、结构体数组、结构体指针、结构体做函数参数以及结构体中const的使用

结构体&#xff08;struct&#xff09;是C语言中一种重要的数据类型&#xff0c;它由一组不同类型的成员组成。结构体可以用来表示一个复杂的数据结构&#xff0c;比如一个学生的信息、一个员工记录或者一个矩形的尺寸等。 结构体定义后&#xff0c;可以声明结构体变量&#xf…

NCCoE发布“向后量子密码学迁移”项目进展情况说明书

近日&#xff0c;NIST下属的国家网络安全中心&#xff08;NCCoE&#xff09;发布了一份向后量子密码学迁移&#xff08;Migration to Post-Quantum Cryptography&#xff09;项目情况说明书。该文档简要概述了向后量子密码学迁移项目的背景、目标、挑战、好处和工作流程&#x…

【HTML5高级第二篇】WebWorker多线程、EventSource事件推送、History历史操作

文章目录 一、多线程1.1 概述1.2 体会多线程1.3 多线程中数据传递和接收 二、事件推送2.1 概述2.2 onmessage 事件 三、history 一、多线程 1.1 概述 前端JS默认按照单线程去执行&#xff0c;一段时间内只能执行一件事情。举个栗子&#xff1a;比方说古代攻城游戏&#xff0c…

Jenkins自动构建(Gitee)

Gitee简介安装JenkinsCLI https://blog.csdn.net/tongxin_tongmeng/article/details/132632743 安装Gitee jenkins-cli install-plugin gitee:1.2.7 # https://plugins.jenkins.io/gitee/releases获取安装命令(稍作变更) JenkinsURL Dashboard-->配置-->Jenkins Locatio…

鸿蒙系列-如何使用好 ArkUI 的 @Reusable?

如何使用好 ArkUI 的 Reusable&#xff1f; OpenHarmony 组件复用机制 在ArkUI中&#xff0c;UI显示的内容均为组件&#xff0c;由框架直接提供的称为 系统组件&#xff0c;由开发者定义的称为 自定义组件。 在进行 UI 界面开发时&#xff0c;通常不是简单的将系统组件进行组合…

NIO原理浅析(三)

epoll 首先认识一下epoll的几个基础函数 int s socket(AF_INET, SOCK_STREAM, 0); bind(s, ...); listen(s, ...);int epfd epoll_create(...) epoll_ctl(epfd, ...); //将所有需要监听的socket添加到epfd中while(1) {int n epoll_wait(...);for(接受到数据的socket) {//处…