spring boot面向切面编程aop

一、什么是AOP

AOP,Aspect Oriented Programming,面向切面编程

举个例子来理解
如果我们的业务需要额外做三件事情,判断是否已经登录,记录日志,统计业务执行时长

传统的做法是这样子的:
在这里插入图片描述
而apo的实现是这样的:
在这里插入图片描述

区别在于:
原本的做法是,需要什么功能,就调用什么功能的方法,需要我们主动去调用

aop的做法是,需要什么功能,就把业务交给相应的代理人,由代理人帮我们去完成,是被动完成的

aop做法的好处是:
1、代码解耦
把不相关的功能都抽取出来,需要使用哪个功能就把业务交给专业的代理人,由代理人去完成。需要新功能的时候,直接添加新的代理业务,这样不会对其它的业务造成影响

2、提高开发效率
当需要使用某个功能时,我们不需要关心代理是怎么做的,只需要简单地使用就好了,就像事务注解@Transactional,只要添加了该注解,方法就会代理,获得了事务的功能,简化了开发

二、AOP的实现示例

maven依赖:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>

Logger 注解:

package com.aop.annotation;import java.lang.annotation.*;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Logger {
}

Logger 注解代理类:

package com.aop.aop;import com.aop.annotation.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;/*** LoggerAop代理类*/
@Component
@Aspect
public class LoggerAop {@Around(value = "@annotation(logger)")public Object around(ProceedingJoinPoint pjp, Logger logger) throws Throwable {System.out.println("开始记录日志");Object proceed = pjp.proceed();return proceed;}
}

Loggin 注解:

package com.aop.annotation;import java.lang.annotation.*;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Login {boolean login() default true;
}

Loggin 注解代理类:

package com.aop.aop;import com.aop.annotation.Login;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;/*** LoginAop代理类*/
@Component
@Aspect
public class LoginAop {@Around("@annotation(login)")public Object around(ProceedingJoinPoint pjp, Login login) throws Throwable {System.out.println("开始判断登录");if(login.login()){System.out.println("已经登录,可执行方法");Object proceed = pjp.proceed();return proceed;}else{System.out.println("未登录,不执行方法");return "请先登录!";}}
}

Time注解:

package com.aop.annotation;import java.lang.annotation.*;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Time {
}

Time注解代理类:

package com.aop.aop;import com.aop.annotation.Time;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;import java.util.Date;/*** TimeAop代理类*/
@Component
@Aspect
public class TimeAop {@Around("@annotation(time)")public Object around(ProceedingJoinPoint pjp, Time time) throws Throwable {long time1 = new Date().getTime();Object proceed = pjp.proceed();long time2 = new Date().getTime();System.out.println("运行了"+((Double.valueOf(time2)-time1)/1000) + "秒");return proceed;}}

测试controller类:

package com.aop.controller;import com.aop.annotation.Logger;
import com.aop.annotation.Login;
import com.aop.annotation.Time;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** RestController,即Controller+ResponseBody,将返回结果转为json字符串响应到客户端*/
@RestController
public class HelloController {/*** Logger,打印日志* Login,判断登录* Time,记录运行时间* RequestMapping,请求路径**/@Logger@Login@Time@RequestMapping("/hello")public String hello() throws InterruptedException {/*** sleep,模拟业务时间*/Thread.sleep(500);System.out.println("hello");return "hello";}
}

启动类:

package com.aop;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class AopApplication {public static void main(String[] args) {SpringApplication.run(AopApplication.class, args);}}

启动后测试访问:
在这里插入图片描述
在这里插入图片描述
发现方法已经被代理了

如果把注解Login的login属性改为false,则验证没有登录,方法不会执行
在这里插入图片描述

再次访问:
在这里插入图片描述
在这里插入图片描述

三、测试源码

需要自取
链接:https://pan.baidu.com/s/1imCrOs_DYWT3aO7qdQqoFA?pwd=wk0i
提取码:wk0i

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

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

相关文章

【PHP面试题74】PHP有哪些魔术方法,如何使用他们?

文章目录 一、前言二、模式方法讲解2.1 __construct()2.2 __destruct()2.3 __get()和__set()2.4 __call()和__callStatic()2.5 __toString()2.6 __invoke() 三、总结 一、前言 本文已收录于PHP全栈系列专栏&#xff1a;PHP面试专区。 计划将全覆盖PHP开发领域所有的面试题&…

用于验证 JSON 数据是否符合指定 JSON Schema 的函数,并使用断言进行验证结果

PYTHON 用于验证 JSON 数据是否符合指定 JSON Schema 的函数&#xff0c;并使用断言进行验证结果 from jsonschema import validate, draft7_format_checker, SchemaError, ValidationErrordef jsonschema_assert(code, msg, schema, jsonSchema):assert code codeassert msg…

资深测试总结,自动化测试-JSON+YAML+CSV+Excel数据驱动(详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 数据驱动 在自动…

【Linux】udp服务器实现大型网络聊天室

udp终结篇~ 文章目录 前言一、udp服务器实现大型网络聊天室总结 前言 根据上一篇文章中对于英汉互译和远程操作的两个小功能大家应该已经学会了&#xff0c;我们的目的是让大家可以深刻的理解udp服务器所需要的接口已经实现的简单步骤&#xff0c;下面我们开始实现网络聊天室。…

微信小程序custom-tab-bar

微信小程序自定义tab-bar。 tab-bar使用tdesign中的t-tab-bar 1 在项目下新建custom-tab-bar文件夹&#xff0c;新建index 组件。 1.1 index.wxml中增加t-tab-bar <t-tab-bar value"{{value}}" bindchange"onChange" theme"tag" split&…

STM32单片机语音识别台灯控制系统人检测亮度调节

实践制作DIY- GC00156-语音识别台灯控制系统 一、功能说明&#xff1a; 基于STM32单片机设计-语音识别台灯控制系统 二、功能说明&#xff1a; 电路&#xff1a;STM32F103C系列最小系统串口语音识别模块LED灯板1个红外传感器 1.任何时候没有人则关闭灯。有人可以自动打开灯。…

Python物联网开发-Python_Socket通信开发-Python与Tcp协议物联网设备通信-Socket客户端

一、前言 Python在物联网开发中的重要愈来愈重&#xff0c;因此&#xff0c;掌握Python语言与物联网设备之间的通信就显得尤为重要&#xff0c;可以通过编写Python程序实现获取物联网设备的传感器数值并可以更改物联网设备上的执行器状态。 二、程序实现 首先&#xff0c;当使…

HarmonyOS学习路之方舟开发框架—学习ArkTS语言(基本语法 一)

初识ArkTS语言 ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript&#xff08;简称TS&#xff09;生态基础上做了进一步扩展&#xff0c;继承了TS的所有特性&#xff0c;是TS的超集。因此&#xff0c;在学习ArkTS语言之前&#xff0c;建议开发者具备TS语…

LeetCode解题记录(一)

1、两数之和 题目描述&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 示例 1&#xff1a;输入&#xff1a;nums [2,7,11,15], target 9 输出&#xff1…

LangChain(3)对话缓存方式 Conversational Memory

LLM 默认是无状态的&#xff0c;即询问当前的问题与上下文无关&#xff0c;当我们需要将多轮对话信息给到LLM 时&#xff0c;就需要使用缓存Memory。缓存方式有多种。 from langchain import OpenAI from langchain.chains import ConversationChain# first initialize the la…

Linux内核的任务:

硬件与软件之间的中间层&#xff1a;内核在技术层面上充当硬件和软件之间的中间层&#xff0c;负责将应用程序的请求传递给硬件&#xff0c;并处理硬件设备和组件的寻址和操作。 应用程序的接口&#xff1a;对于应用程序来说&#xff0c;内核是它们与硬件之间的接口。应用程序通…

抓 https 报文新方案 -Magisk+LSPosed,来试试吧

关于如何抓取Android端https报文&#xff0c;在之前一篇文章中有介绍可以通过VitualXposedJustTrustMe模块禁用SSL验证&#xff0c;这样可以抓取到https&#xff0c;还是有一些同学反馈以下的一些问题&#xff1a; App在低版本的Android上不兼容&#xff0c;需要用高版本的And…

uniapp 集成七牛云,上传图片

1 创建项目 我是可视化创建项目的 &#xff0c;cli创建的项目可以直接使用npm安装七牛云。 2 拷贝qiniuUploader.js到项目&#xff0c;下面的回复 放了qiniuUploader.js百度云链接。 3 在需要使用qiniuUploader的vue文件 引入。 4 相册选择照片&#xff0c;或者拍照后&#xff…

视频问答新增或修改视频问答

通过问答id新增或修改视频问答题目 新增或修改视频问答 图3&#xff1a;视频问答功能&#xff08;观看效果&#xff09; 图4&#xff1a;视频问答功能&#xff08;观看效果&#xff09; 图5&#xff1a;视频问答功能&#xff08;观看效果&#xff09; 单元测试 Testpublic voi…

zabbix 6.0 监控LNPM环境

这里的LNPM是指Linux&#xff0c;Nginx,php-fpm和Mysql.具体版本如下。 Linux : centos7.9Nginx: 1.22.1php-fpm:7.4Mysql: 8.0 一、centos7.9 编译安装Nginx 为了弄清楚Nginx各种配置&#xff0c;我们采用编译安装的形式部署Nginx。 1.下载安装包 首先下载Nginx软件包&am…

oracle unpivot用法

Oracle UNPIVOT函数是将列旋转为行的一种方式。UNPIVOT函数可以将多个列转换为对应的行&#xff0c;以便进行聚合或插入操作。UNPIVOT函数可以将多个列转换为对应的行&#xff0c;以便进行聚合或插入操作。下面是使用UNPIVOT函数的示例&#xff1a; 假设我们有一个表&#xff…

为什么媒体和创意工作者更喜欢 Splashtop 进行远程访问

在当今快速发展的数字环境中&#xff0c;可靠的远程访问已成为全球媒体和创意工作者不可或缺的工具。 远程访问让创意工作者不再受传统办公空间边界的限制&#xff0c;完全实现了随时随地办公。无论是实时剪辑、高分辨率渲染还是其他创意任务&#xff0c;创意工作者对高性能远…

​LeetCode解法汇总874. 模拟行走机器人

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a;力扣 描述&#xff1a; 机器人在一个无限大小的 XY 网格平面上行走&#xff0c;从点 (0, 0) 处开始出发…

ENSP实验四:搭建VPN(GRE,配置安全策略)

首先分析一下数据的流向&#xff1a; PC1->PC2 1、FW1&#xff1a;trust->dmz 【192.168.1.1->192.168.2.1 ICMP】 2、AR1->AR2&#xff1a;【202.1.1.1->202.1.3.1|GRE|192.168.1.1->192.168.2.1 icmp】 3、FW2&#xff1a; ①untrust->local …

kotlin中使用Room数据库(包含升降级崩溃处理)

目录 1.导入依赖库 2.数据实体类 3.数据访问对象 (DAO) 4.数据库类 5.调用DAO里面的“增、删、改、查”方法 6.数据库升降级处理 升级&#xff08;保存数据库历史数据&#xff09;&#xff1a; 升级&#xff08;不保存数据库历史数据&#xff09;&#xff1a; 降级&…