当前位置: 首页 > news >正文

Spring入门篇6 --- AOP

目录

1.核心概念

AOP(Aspect Oriented Programming)面向切面编程:一种编程范式,指导开发者如何组织程序结构

作用:在不惊动原始设计的基础上为其进行功能增强。

连接点(JoinPoint):程序执行过程中的任意位置

切入点(PointCut):匹配连接点的式子

通知(Advice):在切入点执行的操作

切面(Aspect):描述通知与切入点的对应关系

2.小案例

目标:在接口执行前输出当前系统时间。

①在pom.xml中导入依赖spring-context、aspectjweaver

②定义dao接口与实现类

/src/main/java/com/itheima/dao/BookDao.java

package com.itheima.dao;public interface BookDao {public void save();public void update();
}

/src/main/java/com/itheima/dao/impl/BookDaoImpl.java

package com.itheima.dao.Impl;
import com.itheima.dao.BookDao;
import org.springframework.stereotype.Repository;@Repository
public class BookDaoImpl implements BookDao {public void save() {System.out.println(System.currentTimeMillis());System.out.println("book dao save ...");}public void update(){System.out.println("book dao update ...");}
}

③定义通知类

/src/main/java/com/itheima/aop/MyAdvice.java

package com.itheima.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;//通知类必须配置成Spring管理的bean
@Component
//设置当前类为切面类类
@Aspect
public class MyAdvice {//设置切入点,要求配置在方法上方@Pointcut("execution(void com.itheima.dao.BookDao.update())")private void pt(){}//设置在切入点pt()的前面运行当前操作(前置通知)@Before("pt()")public void method(){System.out.println(System.currentTimeMillis());}
}

/src/main/java/com/itheima/config/SpringConfig.java

package com.itheima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration
@ComponentScan("com.itheima")
//开启注解开发AOP功能
@EnableAspectJAutoProxy
public class SpringConfig {
}

④测试

/src/main/java/com/itheima/App.java

package com.itheima;
import com.itheima.config.SpringConfig;
import com.itheima.dao.BookDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);BookDao bookDao = ctx.getBean(BookDao.class);bookDao.update();}
}

3.AOP工作流程

  • Spring容器启动

  • 读取所有切面配置中的切入点

  • 初始化bean,判定bean对应类中的方法是否匹配到任意切入点

  • 匹配失败,获取的bean还是原来的bean

  • 匹配成功,获取的bean是原始对象的代理对象,从而不仅能运行原来的一些方法,还能运行增强的内容。

4.通知类型

前置通知

后置通知

环绕通知(重点)

返回后通知

抛出异常后通知

5.AOP通知获取数据

①获取切入点方法的参数

  • JoinPoint:使用于前置、后置、返回后、抛出异常后通知

  • ProceedJoinPoint:适用于环绕通知

②获取切入点方法的返回值

  • 返回后通知

  • 环绕通知

③获取切入点方法的运行异常信息

  • 抛出异常后通知

  • 环绕通知

pom.xml和/src/main/java/com/itheima/config/SpringConfig.java同上面的案例

/src/main/java/com/itheima/dao/BookDao.java

package com.itheima.dao;public interface BookDao {public String findName(int id);
}

/src/main/java/com/itheima/dao/impl/BookDaoImpl.java

package com.itheima.dao.impl;import com.itheima.dao.BookDao;
import org.springframework.stereotype.Repository;@Repository
public class BookDaoImpl implements BookDao {public String findName(int id) {System.out.println("id:"+id);return "fyx";}
}

/src/main/java/com/itheima/aop/MyAdvice.java

package com.itheima.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.Arrays;//通知类必须配置成Spring管理的bean
@Component
//设置当前类为切面类类
@Aspect
public class MyAdvice {//设置切入点,要求配置在方法上方@Pointcut("execution(* com.itheima.dao.BookDao.findName(..))")private void pt(){}//设置在切入点pt()的前面运行当前操作(前置通知)@Before("pt()")public void before(JoinPoint jp) {Object[] args = jp.getArgs();System.out.println(Arrays.toString(args));System.out.println("before advice ...");}// @After("pt()")public void after(JoinPoint jp) {Object[] args = jp.getArgs();System.out.println(Arrays.toString(args));System.out.println("after advice ...");}//@Around("pt()")public Object around(ProceedingJoinPoint pjp) throws Throwable {Object[] args = pjp.getArgs();System.out.println(Arrays.toString(args));args[0] = 666;Object ret = pjp.proceed(args); // 获取参数处理之后再发送回去return ret;}//@AfterReturning(value="pt()",returning = "ret")public void afterReturning(String ret) {System.out.println("afterReturning advice " + ret);}//@AfterThrowing(value="pt()",throwing = "t")public void afterThrowing(Throwable t) {System.out.println("afterThrowing advice " + t);}
}

/src/main/java/com/itheima/App.java

package com.itheima;import com.itheima.config.SpringConfig;
import com.itheima.dao.BookDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);BookDao bookDao = ctx.getBean(BookDao.class);String name = bookDao.findName(100);System.out.println(name);}
}

6.AOP补充案例

需求:网盘分享链接输入密码时处理尾部多余空格

pom.xml和/src/main/java/com/itheima/config/SpringConfig.java同上面的案例

/src/main/java/com/itheima/dao/ResourcesDao.java

package com.itheima.dao;public interface ResourcesDao {boolean readResources(String url, String password);
}

/src/main/java/com/itheima/dao/impl/ResourcesDaoImpl.java

package com.itheima.dao.impl;import com.itheima.dao.ResourcesDao;
import org.springframework.stereotype.Repository;@Repository
public class ResourcesDaoImpl implements ResourcesDao {public boolean readResources(String url, String password) {// 模拟校验return password.equals("root");}
}

/src/main/java/com/itheima/service/ResourcesService.java

package com.itheima.service;public interface ResourcesService {public boolean openURL(String url, String password);
}

/src/main/java/com/itheima/service/impl/ResourcesServiceImpl.java

package com.itheima.service.impl;import com.itheima.dao.ResourcesDao;
import com.itheima.service.ResourcesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class ResourcesServiceImpl implements ResourcesService {@Autowiredprivate ResourcesDao resourcesDao;@Overridepublic boolean openURL(String url, String password) {return resourcesDao.readResources(url, password);}
}

/src/main/java/com/itheima/aop/DateAdvice.java

package com.itheima.aop;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;@Component
@Aspect
public class DateAdvice {//设置切入点,要求配置在方法上方@Pointcut("execution(boolean com.itheima.service.*Service.openURL(*,*))")private void servicePt(){}@Around("DateAdvice.servicePt()")public Object around(ProceedingJoinPoint pjp) throws Throwable {Object[] args = pjp.getArgs();for(int i = 0; i < args.length; i++) {// 判断参数是不是字符串if(args[i].getClass().equals(String.class)) {args[i] = args[i].toString().trim();}}Object ret = pjp.proceed(args);return ret;}
}

/src/main/java/com/itheima/App.java

package com.itheima;import com.itheima.config.SpringConfig;
import com.itheima.service.ResourcesService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);ResourcesService resourcesService = ctx.getBean(ResourcesService.class);boolean flag = resourcesService.openURL("https://pan.baidu.com/hh", "root ");System.out.println(flag);}
}

相关文章:

Spring入门篇6 --- AOP

目录1.核心概念AOP(Aspect Oriented Programming)面向切面编程&#xff1a;一种编程范式&#xff0c;指导开发者如何组织程序结构作用&#xff1a;在不惊动原始设计的基础上为其进行功能增强。连接点(JoinPoint)&#xff1a;程序执行过程中的任意位置切入点(PointCut)&#xff…...

linux 配置java环境

1、上传jdk包到/usr/local/java目录下 2、解压jdk的tar包 tar -zxvf jdk-8u291-linux-x64.tar.gz 3、添加配置&#xff08;环境变量&#xff09; 注意&#xff1a;JAVA_HOME值为实际jdk路径 打开配置文件 vi /etc/profile 最下面添加: #set java environment JAVA_HOME/usr/…...

分布式事务基础入门

分布式事务基础入门 什么是分布式事务 什么是分布式事务&#xff1f; 首先理解什么是本地事务&#xff1f; 平常我们在程序中通过spring去控制事务是利用数据库本身的事务特性来实现的&#xff0c;因此叫数据库事务&#xff0c;由于应用主要靠关系数据库来控制事务&#xff0…...

白盒测试究竟怎么做

大家好&#xff0c;我是洋子 在进行日常测试的时候&#xff0c;我们大部分时间花在手动的功能测试上&#xff0c;功能测试又可称为手工测试&#xff0c;官方一点的学名叫黑盒测试&#xff0c;当然作为测试工程师&#xff0c;我们一般俗称点点点 黑盒测试是一种软件测试方法&am…...

EEG微状态的功能意义

导读大脑的瞬时全局功能状态反映在其电场结构上。聚类分析方法一致地提取了四种头表面脑电场结构&#xff0c;这些结构能够最佳地解释自发EEG记录中随时间变化的差异。这四种结构被称为EEG微状态A、B、C和D类&#xff0c;分别与言语/语音、视觉、主观感受-自主加工和注意力重定…...

Python3 - Flask+swift实现单点登录

基于 Flask 和 Redis 实现单设备登录的服务端代码和客户端swift、oc代码&#xff1a; Python flask 实现服务端 from flask import Flask, jsonify, request from redis import Redisapp Flask(__name__) redis_db Redis()# 用户登录接口&#xff0c;验证用户名和密码&#…...

HTML URL

文章目录HTML URLURL - 统一资源定位器常见的 URL SchemeURL 字符编码URL 编码实例HTML URL URL 是一个网页地址。 URL可以由字母组成&#xff0c;如"csdn.net"&#xff0c;或互联网协议&#xff08;IP&#xff09;地址&#xff1a; 192.168.100.1。大多数人进入网站…...

带你了解ICCV、ECCV、CVPR三大国际会议

文章目录 前言 一、ICCV、ECCV、CVPR是什么? 1.ICCV 2.ECCV 3.CVPR 二、三大会链接及论文下载链接 前言  作为刚入门CV的新人,有必要记住计算机视觉方面的三大顶级会议:ICCV,CVPR,ECCV,统称为ICE。 与其它学术领域不同,计算机科学使用会议而不是期刊作为发表研究成果的主…...

常用的一些代码

今天菜鸟涨工资了&#xff0c;到手估计有8000左右了&#xff0c;有点开心&#xff0c;本来想上一篇就把这篇写了的&#xff0c;但是发现还是分开写比较好&#xff01; 文章目录自适应js禁止放大播放声音store的使用websocket封装echarts实现渐变swiper常用的陌生方法&#xff0…...

Python-df.pop()和np.array.shape()属性

1.df.pop() 删除某一列 可以使用这个来删除某一列&#xff08;不能是多列&#xff09;&#xff0c;只有一个参数&#xff0c;就是列名&#xff0c;可以是str类型&#xff0c;函数返回的是被删除的列&#xff0c;df直接是删除后的df&#xff0c;不需要我们处理。 我们建模时&a…...

多线程并发编程笔记03(小滴课堂)---线程安全性

原子性操作&#xff1a; 这样一段代码。 我们输出一下&#xff1a; 我们发现它的结果和我们想的不太一样。 正常应该输出1000. 这是因为没有保证原子性。 所以我们来加上原子性&#xff1a; 这样就保证了我们的原子性。 接下来我们来细说说这个关键字&#xff1a; 我发现我…...

提升代码质量,使用插件对 java 代码进行扫描检查分析

目录前言一、使用maven-checkstyle-plugin插件1. maven-checkstyle-plugin 介绍2.引入依赖3.使用二、使用 idea 插件1.安装2.使用前言 很多时候我们的代码写的不规范&#xff0c;比如没缩进、参数间没空格、导入的包没用到没删除、方法很长没有进行拆分、 直接对方法参数进行了…...

如何用秒验提升用户体验和转换率?

手机号验证是移动应用开发中常见的需求&#xff0c;它可以用于用户注册、登录、身份认证等场景。目前&#xff0c;市场上主要的手机号验证方式是短信验证码&#xff0c;但这种方式存在一些问题&#xff0c;例如&#xff1a; 延迟&#xff1a;短信验证码需要等待运营商发送和用…...

【新】(2023Q2模拟题JAVA)华为OD机试 - 机器人活动区域

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:机器人活动区域 题目 现有一…...

2023软件测试面试真题宝典大汇总,没收藏的都后悔了

下边是我根据工作这几年来的面试经验&#xff0c;加上之前收集的资料&#xff0c;整理出来350道软件测试工程师 常考的面试题。字节跳动、阿里、腾讯、百度、快手、美团等大厂常考的面试题&#xff0c;在文章里面都有提到。 虽然这篇文章很长&#xff0c;但是绝对值得你点击一…...

十、MyBatis的逆向工程

一、MyBatis的逆向工程 正向工程:先创建java实体类&#xff0c;由框架负责根据实体类生成数据库表。Hibernate是支持正向工程逆向工程:先创建数据库表&#xff0c;由框架负责根据数据库表&#xff0c;反向生成如下资源&#xff1a; Java实体类 Mapper接口 Mapper映射文件 1.创…...

网站是怎么屏蔽脏话的呢:简单学会SpringBoot项目敏感词、违规词过滤方案

一个社区最重要的就是交流氛围与审查违规&#xff0c;而这两者都少不了对于敏感词进行过滤的自动维护措施。基于这样的措施&#xff0c;我们才能基本保证用户在使用社区的过程中&#xff0c;不至于被敏感违规词汇包围&#xff0c;才能够正常的进行发布帖子和评论&#xff0c;享…...

kafka经典面试题

这里写目录标题1.生产者1.1 生产者发送原理1.2 分区有什么好处?1.3 生产消息时, 是如何决定消息落盘到哪个分区的?1.4 生产者如何提高吞吐量1.5 如何保证生产的消息不丢失(能成功落盘)1.6 ack为-1, 就肯定不会丢失数据吗?1.7 生产者重复发送消息的场景1.8 生产者如何保证数据…...

我的CSDN笔记总索引(阅读量降序,代码自动遍历生成HTML5源码)

Python代码用Linux命令行工具crul获取CSDN博文页面源码&#xff0c;Python内置re正则解析出博文笔记信息。 (本文获得CSDN质量评分【xx】)【学习的细节是欢悦的历程】Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学…...

修改Windows hosts文件的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

龙为权,凰为心:凰标守住文化最柔软的底线@凤凰标志

龙为权凰为心 中国文艺生态的双轨平衡宣言秩序权力与创作初心&#xff0c;一刚一柔&#xff0c; 如日月轮值&#xff0c;缺一不可。 龙标掌「权」&#xff0c;凰标守「心」&#xff0c; 双轨并行&#xff0c;方可让文化既筋骨强健&#xff0c;又血肉温润。一、龙标&#xff1a;…...

从单场到多场并发:知识竞赛平台的弹性扩展能力

&#x1f680; 从单场到多场并发&#xff1a;知识竞赛平台的弹性扩展能力动态调度 平滑扩容 稳定支撑&#x1f4cc; 演进中的需求&#xff1a;从单一活动到复杂场景传统的知识竞赛活动往往以单场、线下或小规模在线形式进行&#xff0c;对技术平台的压力相对有限。然而&#…...

AI编程助手配置统一管理:code-agnostic实现多编辑器配置同步

1. 项目概述&#xff1a;告别配置碎片化&#xff0c;一个中心管理所有AI编辑器如果你和我一样&#xff0c;同时在使用Cursor、OpenCode、Codex甚至Claude Code这些AI编程助手&#xff0c;那你一定对配置管理的混乱深有体会。每个编辑器都有一套自己的配置格式和存放位置&#x…...

别再让Future.get()拖慢你的并发程序!手把手教你用CompletionService优化Java任务结果获取

解锁Java并发新姿势&#xff1a;CompletionService如何让任务结果获取效率翻倍 想象一下这样的场景&#xff1a;你精心设计的线程池正在处理一批耗时各异的任务&#xff0c;有的像闪电般完成&#xff0c;有的却像老牛拉车。当你用Future.get()逐个获取结果时&#xff0c;系统却…...

别再为Matlab App打包发愁了!手把手教你从Web部署到桌面应用(含Runtime安装避坑)

从零到一&#xff1a;Matlab App Designer全流程打包实战指南 第一次尝试将Matlab App Designer开发的应用程序打包成可执行文件时&#xff0c;那种既期待又忐忑的心情相信很多开发者都深有体会。作为一款强大的交互式开发环境&#xff0c;Matlab App Designer让图形用户界面(G…...

SoC硅验证挑战与ClearBlue解决方案解析

1. SoC硅验证与调试的挑战与ClearBlue解决方案在复杂SoC芯片的开发周期中&#xff0c;硅验证阶段往往是最耗时、成本最高且最难预测的环节。当第一颗芯片从晶圆厂返回时&#xff0c;设计团队面临的核心挑战是&#xff1a;如何在真实工作环境和全速运行条件下&#xff0c;快速验…...

如何快速掌握 AI 工具应用能力

先选常用工具&#xff0c;聚焦深耕不用贪多&#xff0c;熟练 2-3 款主流大模型、AI 办公、AIGC 工具&#xff0c;专注实操&#xff0c;不盲目跟风换工具。学好提示词使用技巧学会清晰、具体、结构化提问&#xff0c;精准下达指令&#xff0c;让 AI 高质量完成文案、整理、解题、…...

光纤链路故障排查:从指示灯误导到光功率测量的工程实践

1. 项目概述&#xff1a;一个关于“指示灯谎言”的工程教训在电子工程和测试测量领域&#xff0c;我们习惯于依赖设备上的指示灯——那些绿色、红色或琥珀色的小灯——来快速判断系统状态。它们是我们与复杂硬件对话的直观语言。然而&#xff0c;今天我想分享一个十多年前的真实…...

为AI智能体注入人类洞察:用户研究技能全链路实践指南

1. 项目概述&#xff1a;为AI智能体注入“人类洞察层”如果你正在构建或使用AI智能体&#xff0c;无论是Claude Code、Cursor还是其他基于代码的智能助手&#xff0c;你可能会发现一个核心瓶颈&#xff1a;这些智能体虽然能处理代码、分析数据&#xff0c;但在涉及产品决策、功…...

从「LLM 使用者」到「LLM 驾驭者」:小白程序员必备的大模型核心知识体系与实战指南(收藏版)

本文将从底层原理、工程落地、应用优化三个维度&#xff0c;系统拆解大语言模型的核心知识体系&#xff0c;既保证技术深度&#xff0c;又用通俗的语言和实战案例降低理解门槛&#xff0c;适合所有想要从「LLM 使用者」进阶为「LLM 驾驭者」的读者。 一、LLM 核心原理入门&…...