Java Spring AOP代码3分钟快速入手
AOP
Spring入门(十):Spring AOP使用讲解 - 掘金
maven的依赖:
<dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId>
</dependency>
<!--aspectj支持-->
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId>
</dependency>
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId>
</dependency>
demo1
基于注解实现
AopAnnotation:
package com.example.learn.aop;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface AopAnnotation {
}
TestAspect:
package com.example.learn.aop;import lombok.extern.slf4j.Slf4j;
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.stereotype.Component;@Aspect
@Component
@Slf4j
public class TestAspect {@Pointcut("@annotation(com.example.learn.aop.AopAnnotation)")private void cut() {}@Around("cut()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {log.info("====环绕通知start");// 注解所切的方法所在类的全类名String typeName = joinPoint.getTarget().getClass().getName();log.info("目标对象:[{}]", typeName);// 注解所切的方法名String methodName = joinPoint.getSignature().getName();log.info("所切方法名:[{}]", methodName);StringBuilder sb = new StringBuilder();// 获取参数Object[] arguments = joinPoint.getArgs();for (Object argument : arguments) {sb.append(argument.toString());}log.info("所切方法入参:[{}]", sb.toString());// 统计方法执行时间long start = System.currentTimeMillis();//执行目标方法,并获得对应方法的返回值Object result = joinPoint.proceed();log.info("返回结果:[{}]", result);long end = System.currentTimeMillis();log.info("====执行方法共用时:[{}]", (end - start));log.info("====环绕通知之结束");return result;}}
实现一个被织入的类,注意这个类得是Bean,一般aop都是针对容器的,针对普通类的很少且不常用:
AopClass:
package com.example.learn.aop;import org.springframework.stereotype.Component;@Component
public class AopClass {@AopAnnotationpublic void testAop() {System.out.println("func invoked!");}
}
测试:
正是因为AOP是针对Bean的,因此测试的时候不要像下面这样去测试,因为new出来的这个对象没有被Spring管理:
@SpringBootTest
class LearnApplicationTests {@Testvoid contextLoads() {AopClass aopClass = new AopClass();aopClass.testAop();}}
憨憨行为。应该注入容器来测试:
@SpringBootTest
class LearnApplicationTests {@Autowiredprivate AopClass aopClass;@Testvoid contextLoads() {aopClass.testAop();}}
打印结果:
. ____ _ __ _ _/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) )' |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot :: (v2.5.5)2023-10-27 10:56:13.600 INFO 16048 --- [ main] com.example.learn.LearnApplicationTests : Starting LearnApplicationTests using Java 1.8.0_381 on DESKTOP-NFN5QCN with PID 16048 (started by DELL in F:\OneDrive\Java学习\yunfei\learn)
2023-10-27 10:56:13.604 INFO 16048 --- [ main] com.example.learn.LearnApplicationTests : No active profile set, falling back to default profiles: default
2023-10-27 10:56:15.202 INFO 16048 --- [ main] com.example.learn.LearnApplicationTests : Started LearnApplicationTests in 1.916 seconds (JVM running for 2.886)
2023-10-27 10:56:15.408 INFO 16048 --- [ main] com.example.learn.aop.TestAspect : ====环绕通知start
2023-10-27 10:56:15.408 INFO 16048 --- [ main] com.example.learn.aop.TestAspect : 目标对象:[com.example.learn.aop.AopClass]
2023-10-27 10:56:15.410 INFO 16048 --- [ main] com.example.learn.aop.TestAspect : 所切方法名:[testAop]
2023-10-27 10:56:15.410 INFO 16048 --- [ main] com.example.learn.aop.TestAspect : 所切方法入参:[]
func invoked!
2023-10-27 10:56:15.420 INFO 16048 --- [ main] com.example.learn.aop.TestAspect : 返回结果:[null]
2023-10-27 10:56:15.420 INFO 16048 --- [ main] com.example.learn.aop.TestAspect : ====执行方法共用时:[10]
2023-10-27 10:56:15.420 INFO 16048 --- [ main] com.example.learn.aop.TestAspect : ====环绕通知之结束
demo2
写一个切面类:
package com.example.base.aop;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;@Aspect
public class Detector {@Pointcut("execution(* com.example.base.AopController.hello(..))")public void helloAspect() {}@Before("helloAspect()")public void beforeAction() {System.out.println("before hello~");}@After("helloAspect()")public void afterAction() {System.out.println("after hello~");}@AfterReturning("helloAspect()")public void afterReturningAction() {System.out.println("after return~");}@Around("helloAspect()")public Object aroundAction(ProceedingJoinPoint pjp) throws Throwable {System.out.println("around~");pjp.proceed();System.out.println("around~");return null;}
}
切点为Controller的一个方法:
package com.example.base;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class AopController {@GetMapping("/hello")public String hello(@RequestParam("id") int userId) {return null;}
}
写切面的配置类,自动加载切面:
package com.example.base.aop;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class Config {@Beanpublic Detector detector() {return new Detector();}
}
启动项目,浏览器http://localhost:8080/hello?id=1 触发打印:
2023-09-06 15:49:32.974 INFO 198380 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-09-06 15:49:32.974 INFO 198380 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2023-09-06 15:49:32.975 INFO 198380 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
around~
before hello~
after return~
after hello~
around~
Disconnected from the target VM, address: '127.0.0.1:61026', transport: 'socket'
相关文章:
Java Spring AOP代码3分钟快速入手
AOP Spring入门(十):Spring AOP使用讲解 - 掘金 maven的依赖: <dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId> </dependency> <!--aspectj支持--> <dependen…...
.NET开源快速、强大、免费的电子表格组件
今天大姚给大家分享一个.NET开源(MIT License)、快速、强大、免费的电子表格组件,支持数据格式、冻结、大纲、公式计算、图表、脚本执行等。兼容 Excel 2007 (.xlsx) 格式,支持WinForm、WPF和Android平台:ReoGrid。 项…...
docker一键部署若依前后端分离版本
比如这里把文件放到/xin/docker/jiaoZ/的目录下,jar包和下面的配置文件都放在这个文件夹下。 注意要把jar端口改为你实际启动的,映射端口也可以改为你想要的。 这里的映射端口为:nginx监听80端口,jar在8620端口,mysq…...
Java项目开发之fastjson详解
Fastjson 是由阿里巴巴公司开发的一个 Java 语言编写的高性能 JSON 处理库。它主要用于 Java 对象与 JSON 数据格式之间的转换,提供了简单易用的 API 来实现序列化(Java 对象转 JSON 字符串)和反序列化(JSON 字符串转 Java 对象&a…...
面试算法-62-盛最多水的容器
题目 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明:你不能倾斜容器。…...
【智能算法】海洋捕食者算法(MPA)原理及实现
目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2020年,Afshin Faramarzi 等人受到海洋生物适者生存启发,提出了海洋捕食者算法(Marine Predators Algorithm,MPA)。 2.算法原理 2.1算法思想 MPA根据模拟自然界…...
刷题DAY24 | LeetCode 77-组合
1 回溯法理论基础 回溯法也可以叫做回溯搜索法,它是一种搜索的方式。回溯是递归的副产品,只要有递归就会有回溯。 所以以下讲解中,回溯函数也就是递归函数,指的都是一个函数。 1.1 回溯法的效率 回溯法的性能如何呢࿰…...
Spring Boot为什么默认使用CGLIB动态代理
兼容性: 1. CGLIB 动态代理可以代理任何类型的目标类,无论它是否实现了接口;[注意的是,类被 final 修饰,那么该不可被继承,即不可被代理;同样,类中 final 修饰的方法&am…...
算法详解——Dijkstra算法
Dijkstra算法的目的是寻找单起点最短路径,其策略是贪心加非负加权队列 一、单起点最短路径问题 单起点最短路径问题:给定一个加权连通图中的特定起点,目标是找出从该起点到图中所有其他顶点的最短路径集合。需要明确的是,这里关心…...
利用GANs进行图像生成
生成对抗网络(GANs)是一种深度学习模型,由两部分组成:生成器(Generator)和判别器(Discriminator)。它们通过相互竞争来提高生成器生成高质量图像的能力。以下是如何利用GANs进行图像…...
Flutter-底部弹出框(Widget层级)
需求 支持底部弹出对话框。支持手势滑动关闭。支持在widget中嵌入引用。支持底部弹出框弹出后不影响其他操作。支持弹出框中内容固定头部和下面列表时,支持触摸头部并在列表不在头部的时候支持滑动关闭 简述 通过上面的需求可知,就是在界面中可以支持…...
聚焦两会:数字化再加速,VR全景助力制造业转型
近年来,随着信息技术、人工智能、VR虚拟现实等新兴技术的不断涌现,数字化正日益成为推动当今经济发展的新驱动力。在不久前的两会上,数字化经济和创新技术再度成为热门话题: 国务院总理李强作政府工作报告: 要深入推…...
数据挖掘之关联规则
“啤酒和尿布的荣誉” 概念 项 item:单个的事物个体 ,I{i1,i2…im}是所有项的集合,|I|m是项的总数项集(item set)/模式(pattern):项的集合,包含k个项的项集称为k-项集数据集(data set)/数据库…...
java:java.util.BitSet对象的Jackson序列化和反序列化实现
java.util.BitSet是个非常方便的比特位数据存储和操作类,一个 bit 具有2个值:0和1,正好可以用来表示 false 和 true,适用于判断“数据是否存在”的场景。 但是,这个从JDK1.0版本就存在的类,Jackson,Fastjso…...
Go语言学习01-基本程序结构
文章目录 Go语言学习01-基本程序结构基本程序结构应用程序入口退出返回值编写测试程序快速设置连续值基本数据类型类型的预定义值指针类型运算符算数运算符比较运算符用 比较数组 逻辑运算符位运算符&^ 按位 置零 Go语言学习01-基本程序结构 基本程序结构 package main …...
rundeck k8s部署踩坑
1、镜像启动后原来的定时任务无法运行 参考: https://github.com/rundeck/rundeck/issues/4275 https://stackoverflow.com/questions/60942785/env-variable-for-rundeck-feature-joblifecycleplugin-enabled/60959605#60959605 结论: (1&…...
每天学习几道面试题|Kafka(二)架构设计类
文章目录 1. Kafka 是如何保证高可用性和容错性的?2. Kafka 的存储机制是怎样的?它是如何处理大量数据的?3. Kafka 如何处理消费者的消费速率低于生产者的生产速率?4. Kafka 集群中的 Controller 是什么?它的作用是什么…...
Spring 实现 OAuth2 授权之解决方案
Spring Security OAuth2 - 已经废弃的项目 早期的Spring 使用 Spring Security OAuth2 实现 OAuth 2.0 的认证服务器和资源服务器。OAuth2是一个授权框架,它允许第三方应用获取有限的访问权限,而无需获取用户的账号和密码等敏感信息。通过这种方式,OAuth2协议实现了安全的用…...
el-select使用filterable下拉无法关闭得问题
这里推荐一个前端框架 sakuya / SCUI,他里面有个formTable,可以解决很多订单明细保存得问题。基本沿用element-plus的前端使用模式,让表单表格变的非常容易。 这个的供应商插件,当使用filterable后,点击表格重的选项&…...
基于javaweb(springboot)城市地名地址信息管理系统设计和实现
基于javaweb(springboot)城市地名地址信息管理系统设计和实现 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
