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》,文章主要基于…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用
前言:我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM(Java Virtual Machine)让"一次编写,到处运行"成为可能。这个软件层面的虚拟化让我着迷,但直到后来接触VMware和Doc…...