spring—AOP
系列文章目录
Spring中AOP技术的学习
文章目录
- 系列文章目录
- 前言
- 一、AOP核心概念
- 二、AOP入门案例
- 1.AOP入门案例思路分析
- 2.AOP入门案例实现
- 三、AOP工作流程
- 四、AOP切入点表达式
- 五、AOP通知类型
- 六、案例:测量业务层接口万次执行效率
- 1.项目结构
- 2.实现类
- 七、AOP获取通知数据
- 八、案例:百度网盘密码数据兼容处理
- 总结
前言
一、AOP核心概念


二、AOP入门案例
1.AOP入门案例思路分析

2.AOP入门案例实现







项目结构

三、AOP工作流程


四、AOP切入点表达式




五、AOP通知类型







六、案例:测量业务层接口万次执行效率



1.项目结构

2.实现类
MyAdvice
package org.example.aop;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;@Component
@Aspect
public class MyAdvice {//匹配业务层的所有方法@Pointcut("execution(* org.example.service.*Service.*(..))")private void servicePt() {}@Around("servicePt()")public Object runSpeed(ProceedingJoinPoint point) throws Throwable {//一次执行的签名信息Signature signature = point.getSignature();//获取执行的方法名和类型名String className = signature.getDeclaringTypeName();String methodName = signature.getName();Object ret = null;//记录程序当前执行(开始时间)long begin = System.currentTimeMillis();//业务执行次数for (int i = 0; i < 10000; i++) {//表示对原始操作的调用ret = point.proceed();}//记录程序当前执行时间(结束时间)long end = System.currentTimeMillis();//计算时间差long totalTime = end - begin;//输出信息System.out.println("执行"+className+"."+methodName+"万次消耗时间:" + totalTime + "ms");return ret;}
}
JdbcConfig
package org.example.config;import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;import javax.sql.DataSource;public class JdbcConfig {@Value("${jdbc.driver}")private String drive;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;@Beanpublic DataSource dataSource(){DruidDataSource ds=new DruidDataSource();ds.setDriverClassName(drive);ds.setUrl(url);ds.setUsername(username);ds.setPassword(password);return ds;}
}
MybatisConfig
package org.example.config;import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;import javax.sql.DataSource;public class MybatisConfig {//定义bean,SqlSessionFactoryBean,用于产生SqlSessionFactory对象@Beanpublic SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){SqlSessionFactoryBean ssfb=new SqlSessionFactoryBean();ssfb.setTypeAliasesPackage("org.example.domain");ssfb.setDataSource(dataSource);return ssfb;}//定义bean,返回MapperScannerConfigurer对象@Beanpublic MapperScannerConfigurer mapperScannerConfigurer(){MapperScannerConfigurer msc=new MapperScannerConfigurer();msc.setBasePackage("org.example.dao");return msc;}
}
SpringConfig
package org.example.config;import org.springframework.context.annotation.*;@Configuration
@ComponentScan("org.example")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
@EnableAspectJAutoProxy
public class SpringConfig {
}
AccountDao
package org.example.dao;import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.example.domain.Account;import java.util.List;public interface AccountDao {@Insert("insert into tbl_account(name,money)values(#{name},#{money})")void save(Account account);@Delete("delete from tbl_account where id = #{id} ")void delete(Integer id);@Update("update tbl_account set name = #{name} , money = #{money} where id = #{id} ")void update(Account account);@Select("select * from tbl_account")List<Account> findAll();@Select("select * from tbl_account where id = #{id} ")Account findById(Integer id);
}
Account
package org.example.domain;public class Account {private Integer id;private String name;private Double money;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Double getMoney() {return money;}public void setMoney(Double money) {this.money = money;}@Overridepublic String toString() {return "Account{" +"id=" + id +", name='" + name + '\'' +", money=" + money +'}';}
}
AccountService
package org.example.service;import org.example.domain.Account;import java.util.List;public interface AccountService {void save(Account account);void delete(Integer id);void update(Account account);List<Account> findAll();Account findById(Integer id);
}
AccountServiceImpl
package org.example.service.impl;import org.example.dao.AccountDao;
import org.example.domain.Account;
import org.example.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountDao accountDao;public void save(Account account) {accountDao.save(account);}public void delete(Integer id) {accountDao.delete(id);}public void update(Account account) {accountDao.update(account);}public List<Account> findAll() {return accountDao.findAll();}public Account findById(Integer id) {return accountDao.findById(id);}
}
测试类
package org.example.service;import org.example.config.SpringConfig;
import org.example.domain.Account;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.List;//Spring集成Junit必须要写的注解,否则找不到类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTest {@Autowiredprivate AccountService accountService;@Testpublic void testFindById(){Account account=accountService.findById(2);System.out.println(account);}@Testpublic void testFindAll(){List<Account> accounts=accountService.findAll();System.out.println(accounts);}
}
七、AOP获取通知数据




八、案例:百度网盘密码数据兼容处理


项目结构

DataAdvice
package org.example.aop;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;@Component
@Aspect
public class DataAdvice {@Pointcut("execution(boolean org.example.service.*Service.openURL(*,*))")private void servicePt(){}@Around("servicePt()")public Object trimStr(ProceedingJoinPoint point) throws Throwable {Object[] args = point.getArgs();for (int i = 0; i < args.length; i++) {//判断参数是否为字符串if (args[i].getClass().equals(String.class)){args[i]=args[i].toString().trim();}}Object ret = point.proceed(args);return ret;}
}
SpringConfig
package org.example.config;import org.aspectj.lang.annotation.Around;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration
@ComponentScan("org.example")
@EnableAspectJAutoProxy
public class SpringConfig {
}
ResourceDaoImpl
package org.example.dao.impl;import org.example.dao.ResourceDao;
import org.springframework.stereotype.Repository;@Repository
public class ResourceDaoImpl implements ResourceDao {public boolean readResource(String url, String password) {//模拟校验return password.equals("root");}
}
ResourceDao
package org.example.dao;public interface ResourceDao {public boolean readResource(String url,String password);
}
ResourceServiceImpl
package org.example.service.impl;import org.example.dao.ResourceDao;
import org.example.service.ResourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class ResourceServiceImpl implements ResourceService {@Autowiredprivate ResourceDao resourceDao;public boolean openURL(String url, String password) {return resourceDao.readResource(url,password);}
}
ResourceService
package org.example.service;public interface ResourceService {public boolean openURL(String url,String password);
}
App
import org.example.config.SpringConfig;
import org.example.service.ResourceService;
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);ResourceService resourceService = ctx.getBean(ResourceService.class);boolean flag = resourceService.openURL("http://www.baidu.com", "root");System.out.println(flag);}
}
记得加入相应依赖
总结
AOP主要用作方法的增强,底层使用代理,本节主要讲解了AOP方法的作用和相关案例,详细讲解了AOP相关的核心概念,如:切入点表达式,通知类型等。
参考视频
相关文章:
spring—AOP
系列文章目录 Spring中AOP技术的学习 文章目录系列文章目录前言一、AOP核心概念二、AOP入门案例1.AOP入门案例思路分析2.AOP入门案例实现三、AOP工作流程四、AOP切入点表达式五、AOP通知类型六、案例:测量业务层接口万次执行效率1.项目结构2.实现类七、AOP获取通知…...
自己曾经的C++笔记【在c盘爆满的时候找到的回忆】
文章目录**C与C的区别** (二)类和对象构造函数和析构函数C特殊成员C友元C类的继承C虚函数和多态C模板C可变参模板CSTL容器篇C迭代器C仿函数C函数适配器CSTL算法C智能指针C类型推断CIO流C正则表达式具有特殊意义的元字符量词元字符校验数字的表达式校验字符的表达式特…...
Nginx 实战-负载均衡
一、负载均衡今天学习一下Nginx的负载均衡。由于传统软件建构的局限性,加上一台服务器处理能里的有限性,在如今高并发、业务复杂的场景下很难达到咱们的要求。但是若将很多台这样的服务器通过某种方式组成一个整体,并且将所有的请求平均的分配…...
本周大新闻|128GB版Quest 2再降价,Mojo Vision完成“新A轮”融资
本周XR大新闻,AR方面,DigiLens推出SRG表面浮雕光栅衍射光波导;索尼成立Sony Research;NuEyes推出牙医场景AR眼镜NuLoupes;苹果EMG手环、AR/VR眼球追踪专利公布。 VR方面,128GB版Quest 2降至349美元&#x…...
【论文阅读】如何给模型加入先验知识
如何给模型加入先验知识 1. 基于pretain模型给模型加入先验 把预训练模型的参数导入模型中,这些预训练模型在另一个任务中已经p retrain好了模型的weight,往往具备了一些基本图片的能力 2. 基于输入给模型加入先验 比如说鸟类的头部是一个重要的区分部分&#x…...
arm系列交叉编译器各版本区别
目录交叉编译器命名规则具体编译器举例crosstool-ng交叉编译工具样本arm交叉编译器举例几个概念ABI与EABIgnueabi与gnueabihf参考交叉编译器命名规则 交叉编译器的命名规则:arch [-vendor] [-os] [-(gnu)eabi] [-language] arch - 体系架构, 如arm&…...
随笔记录工作日志
工作中遇到的问题随笔记录 1、将map集合中的key/value数据按照一定的需求过滤出来,并将过滤出来的map的key值存到list集合中 首先想到的是stream流,但是我对stream流的用法基本不熟,记不住方法,如果坚持用stream流去实现这个需求…...
LinkedHashMap源码分析以及LRU的应用
LinkedHashMap源码分析以及LRU的应用 LinkedHashMap简介 LinkedHashMap我们都知道是在HashMap的基础上,保证了元素添加时的顺序;除此之外,它还支持LRU可以当做缓存中心使用 源码分析目的 分析保持元素有序性是如何实现的 LRU是如何实现的…...
【每日一题Day166】LC1053交换一次的先前排列 | 贪心
交换一次的先前排列【LC1053】 给你一个正整数数组 arr(可能存在重复的元素),请你返回可在 一次交换(交换两数字 arr[i] 和 arr[j] 的位置)后得到的、按字典序排列小于 arr 的最大排列。 如果无法这么操作,…...
Canal增量数据订阅和消费——原理详解
文章目录 简介工作原理MySQL主备复制原理canal 工作原理Canal-HA机制应用场景同步缓存 Redis /全文搜索 ES下发任务数据异构简介 canal 翻译为管道,主要用途是基于 MySQL 数据库的增量日志 Binlog 解析,提供增量数据订阅和消费。 早期阿里巴巴因为杭州和美国双机房部署,存…...
为什么要使用线程池
Java线程的创建非常昂贵,需要JVM和OS(操作系统)配合完成大量的工作: (1)必须为线程堆栈分配和初始化大量内存块,其中包含至少1MB的栈内存。 (2)需要进行系统调用,以便在OS(操作系统)…...
在云服务部署前后端以及上传数据库
1.上传数据库(sql文件) 首先建立一个目录,用于存放要部署的sql文件,然后在此目录中进入mysql 进入后建立一个数据库,create database 数据库名 完成后,通过select * from 表名可以查到数据说明导入成功。 2.部署Maven后端 将Ma…...
Onedrive for Business迁移方案 | 分享一
文章目录 前言 一、Onedrive for Business迁移方案应用范围? 1.准备目标平台 2.导出源平台数据 <...
pt01数据类型、语句选择
python01 pycharm常用快捷键 (1) 移动到本行开头:home键 (2) 移动到本行末尾:end键盘 (3) 注释代码:ctrl / (4) 复制行:ctrl d #光标放行上 (5) 删除行:shift delete (6) 选择列:shift alt 鼠标左键…...
ChatGPT 存在很大的隐私问题
当 OpenAI 发布时 2020 年 7 月的 GPT-3,它提供了用于训练大型语言模型的数据的一瞥。 根据一篇技术论文,从网络、帖子、书籍等中收集的数百万页被用于创建生成文本系统。 在此数据中收集的是您在网上分享的一些关于您自己的个人信息,这些数据现在让 O…...
图的迭代深度优先遍历
图的深度优先遍历(或搜索)类似于树的深度优先遍历(DFS)。这里唯一的问题是,与树不同,图可能包含循环,因此一个节点可能会被访问两次。为避免多次处理一个节点,请使用布尔访问数组。 例子: 输入: n = 4, e = 6 0 -> 1, 0 -> 2, 1 -> 2, 2 -> 0, …...
华为OD机试-开放日活动-2022Q4 A卷-Py/Java/JS
某部门开展Family Day开放日活动,其中有个从桶里取球的游戏,游戏规则如下:有N个容量一样的小桶等距排开,且每个小桶都默认装了数量不等的小球, 每个小桶装的小球数量记录在数组 bucketBallNums 中,游戏开始时,要求所有…...
两亲性聚合物:Lauric acid PEG Maleimide,Mal-PEG-Lauric acid,月桂酸PEG马来酰亚胺,试剂知识分享
Lauric acid PEG Maleimide,Lauric acid PEG Mal| 月桂酸PEG马来酰亚胺 | CAS:N/A | 端基取代率:95%一、试剂参数信息: 外观(Appearance):灰白色/白色固体或粘性液体取决于分子量 溶解性&am…...
FB使用入口点函数例子
一、DLL的入口点 1.1 VFB的自带DLL模式入口 FB是把代码转成C(GCC编译)或者汇编(GAS编译)后编译的,本身就有一个main函数,所以在程序里其实不需要入口点,直接写就可以顺序执行,而有的…...
学习周报4/9
文章目录前言文献阅读摘要简介方法结论时间序列预测总结前言 本周阅读文献《Improving LSTM hydrological modeling with spatiotemporal deep learning and multi-task learning: A case study of three mountainous areas on the Tibetan Plateau》,文章主要基于…...
Qwen3-0.6B-FP8在SolidWorks设计中的应用探索
Qwen3-0.6B-FP8在SolidWorks设计中的应用探索 1. 引言 作为一名机械设计师,你是否曾经遇到过这样的困扰:在SolidWorks中反复调整参数却始终达不到理想效果,或者设计完成后才发现某个关键尺寸存在冲突?传统的设计流程往往依赖设计…...
XCOM 2模组管理终极解决方案:AML启动器效率革命指南
XCOM 2模组管理终极解决方案:AML启动器效率革命指南 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/…...
WAF工程师实战笔记:如何用Suricata规则精准识别哥斯拉、冰蝎、蚁剑的Webshell流量
WAF工程师实战笔记:Suricata规则精准识别主流Webshell流量 在安全运维的日常工作中,Webshell流量的检测始终是一场攻防对抗的持久战。面对哥斯拉、冰蝎、蚁剑等主流Webshell管理工具不断升级的流量混淆技术,传统的特征匹配方法往往力不从心。…...
开源音频格式转换终极指南:ncmdumpGUI实现数字音乐资产自由流转的完整方案
开源音频格式转换终极指南:ncmdumpGUI实现数字音乐资产自由流转的完整方案 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 在数字音乐时代…...
Electron-builder打包Windows应用,我踩过的三个坑(附详细解决方案)
Electron-builder打包Windows应用:三个典型问题的深度解析与实战解决方案 第一次使用electron-builder打包Windows应用时,那种期待与焦虑交织的感觉至今记忆犹新。作为一个从Web前端转向桌面应用开发的程序员,我本以为有了Electron这个跨平台…...
告别调包:手把手教你用PyTorch从零复现CRNN文本识别网络(附完整代码)
从零构建CRNN文本识别引擎:PyTorch实战指南与工业级优化技巧 在计算机视觉领域,文本识别技术正经历着从传统算法到深度学习的革命性转变。当我们谈论OCR(光学字符识别)时,CRNN(卷积循环神经网络࿰…...
运维实战:思科NAT配置全解析与典型场景应用
1. 为什么企业网络离不开NAT技术 想象一下你公司的内网有200台电脑,但ISP只分配了5个公网IP地址——这就是NAT技术大显身手的场景。作为网络工程师,我处理过太多类似案例,最夸张的一个客户用1个公网IP支撑了整个500人办公区的上网需求。 NA…...
Python3.8环境配置全攻略:从零开始搭建你的第一个项目
Python3.8环境配置全攻略:从零开始搭建你的第一个项目 1. 为什么选择Python3.8环境 Python3.8作为Python3系列的一个重要版本,引入了多项新特性,包括海象运算符(:)、位置参数限定符(/)等语法改进,同时在性能上也有显著提升。对于…...
互联网大厂Java求职者面试经历
Java求职面试:严肃面试官与搞笑水货程序员的碰撞 在一次互联网大厂的面试中,面试官坐在桌子后面,脸上挂着严肃的表情,而面试者则是一个搞笑的程序员,名叫谢飞机。 第一轮提问 面试官:请简述一下Java的核心特…...
为什么你的FastAPI AI接口在K8s里流式失败?——基于eBPF追踪的12层网络栈+ASGI生命周期时序图(含cgroup内存隔离失效证据)
第一章:FastAPI 2.0 异步 AI 流式响应对比评测报告FastAPI 2.0 原生强化了对 async/await 的深度支持,尤其在处理大语言模型(LLM)的逐 token 流式生成场景中,显著提升了吞吐量与首字节延迟(TTFB)…...
