SpringAOP入门案例

在这里插入图片描述

package com.elf.spring.aop.aspectj;
/*** @author 45* @version 1.0*/
public interface UsbInterface {public void work();
}
package com.elf.spring.aop.aspectj;
import org.springframework.stereotype.Component;
/*** @author 45* @version 1.0*/
@Component //把Phone对象当做一个组件注入容器
public class Phone implements UsbInterface{@Overridepublic void work() {System.out.println("手机开始工作了....");}
}
package com.elf.spring.aop.aspectj;
import org.springframework.stereotype.Component;
/*** @author 45* @version 1.0*/
@Component //将Camera注入到spring容器
public class Camera implements UsbInterface {@Overridepublic void work() {System.out.println("相机开始工作...");}
}
package com.elf.spring.aop.aspectj;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;import java.util.Arrays;/*** @author 45* @version 1.0* 切面类 , 类似于我们以前自己写的MyProxyProvider,但是功能强大很多**/
@Order(value = 2)//表示该切面类执行的顺序, value的值越小, 优先级越高
@Aspect //表示是一个切面类[底层切面编程的支撑(动态代理+反射+动态绑定...)]
@Component //会注入SmartAnimalAspect到容器
public class SmartAnimalAspect {//定义一个切入点, 在后面使用时可以直接引用, 提高了复用性@Pointcut(value = "execution(public float com.elf.spring.aop.aspectj.SmartDog.getSum(float, float)))")public void myPointCut() {}//希望将f1方法切入到SmartDog-getSum前执行-前置通知/*** 解读* 1. @Before 表示前置通知:即在我们的目标对象执行方法前执行* 2. value = "execution(public float com.elf.spring.aop.aspectj.SmartDog.getSum(float, float)* 指定切入到哪个类的哪个方法  形式是: 访问修饰符 返回类型 全类名.方法名(形参列表),*     带形参列表是因为方法名可能相同,参数个数不同构成重载,以便区分.* 3. showBeginLog方法可以理解成就是一个切入方法, 这个方法名是可以程序员指定  比如:showBeginLog* 4. JoinPoint joinPoint 在底层执行时,由AspectJ切面框架, 会给该切入方法传入 joinPoint对象* , 通过该方法,程序员可以获取到 相关信息** @param joinPoint*///@Before(value = "execution(public float com.elf.spring.aop.aspectj.SmartDog.getSum(float, float))")//这里我们使用定义好的切入点@Before(value = "myPointCut()")//如果说是一个切入方法,那么形参是JoinPoint joinPoint,用aop来做的开发主要是由aspectj框架来支撑的public void showBeginLog(JoinPoint joinPoint) {//通过连接点对象joinPoint 可以获取方法签名Signature signature = joinPoint.getSignature();//signature.getName()方法签名指的是:com.elf.spring.aop.aspectj.SmartDog.getSumSystem.out.println("SmartAnimalAspect-切面类showBeginLog()[使用的myPointCut()]-方法执行前-日志-方法名-" + signature.getName() + "-参数 "+ Arrays.asList(joinPoint.getArgs()));//(float, float)}//返回通知:即把showSuccessEndLog方法切入到目标对象方法正常执行完毕后的地方//老韩解读//1. 如果我们希望把目标方法执行的结果,返回给切入方法//2. 可以再 @AfterReturning 增加属性 , 比如 returning = "res"//3. 同时在切入方法增加 Object res//4. 注意: returning = "res" 和 Object res 的 res名字一致//@AfterReturning(value = "execution(public float com.elf.spring.aop.aspectj.SmartDog.getSum(float, float))", returning = "res")//使用切入点@AfterReturning(value = "myPointCut()", returning = "res")public void showSuccessEndLog(JoinPoint joinPoint, Object res) {Signature signature = joinPoint.getSignature();System.out.println("SmartAnimalAspect-切面类showSuccessEndLog()-方法执行正常结束-日志-方法名-" + signature.getName() + " 返回的结果是=" + res);}//异常通知:即把showExceptionLog方法切入到目标对象方法执行发生异常的的catch{}//@AfterThrowing(value = "execution(public float com.elf.spring.aop.aspectj.SmartDog.getSum(float, float))", throwing = "throwable")//直接使用切入点表达式@AfterThrowing(value = "myPointCut()", throwing = "throwable")public void showExceptionLog(JoinPoint joinPoint, Throwable throwable) {Signature signature = joinPoint.getSignature();System.out.println("SmartAnimalAspect-切面类showExceptionLog()-方法执行异常-日志-方法名-" + signature.getName() + " 异常信息=" + throwable);}//最终通知:即把showFinallyEndLog方法切入到目标方法执行后(不管是否发生异常,都要执行 finally{})//@After(value = "execution(public float com.elf.spring.aop.aspectj.SmartDog.getSum(float, float))")//直接使用切入点@After(value = "myPointCut()")public void showFinallyEndLog(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("SmartAnimalAspect-切面类showFinallyEndLog()-方法最终执行完毕-日志-方法名-" + signature.getName());}//新的前置通知//@Before(value = "execution(public void com.elf.spring.aop.aspectj.Phone.work()) || execution(public void com.elf.spring.aop.aspectj.Camera.work())")//public void hi(JoinPoint joinPoint) {//    Signature signature = joinPoint.getSignature();//    System.out.println("切面类的hi()-执行的目标方法-" + signature.getName());//}//切入表达式也可以指向接口的方法, 这时切入表达式会对实现了接口的类/对象生效//比如下面我们是对UsbInterface 切入,那么对实现类Phone 和 Camera对象都作用了@Before(value = "execution(public void com.elf.spring.aop.aspectj.UsbInterface.work())")public void hi(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("切面类的hi()-执行的目标方法-" + signature.getName());}//给Car配置一个前置通知,即将ok1()方法切入到Car类的run()方法前@Before(value = "execution(public void Car.run())")public void ok1(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("切面类的ok1()-执行的目标方法-" + signature.getName());}//返回通知@AfterReturning(value = "execution(public void Car.run())")public void ok2(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("切面类的ok2()-执行的目标方法-" + signature.getName());}//异常通知@AfterThrowing(value = "execution(public void Car.run())")public void ok3(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("切面类的ok3()-执行的目标方法-" + signature.getName());}//后置通知@After(value = "execution(public void Car.run())")public void ok4(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("切面类的ok4()-执行的目标方法-" + signature.getName());//演示一下JoinPoint常用的方法.joinPoint.getSignature().getName(); // 获取目标方法名joinPoint.getSignature().getDeclaringType().getSimpleName(); // 获取目标方法所属类的简单类名joinPoint.getSignature().getDeclaringTypeName(); // 获取目标方法所属类的类名joinPoint.getSignature().getModifiers(); // 获取目标方法声明类型(public、private、protected)Object[] args = joinPoint.getArgs(); // 获取传入目标方法的参数,返回一个数组joinPoint.getTarget(); // 获取被代理的对象joinPoint.getThis(); // 获取代理对象自己}
}
package com.elf.spring.aop.aspectj;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** @author 45* @version 1.0*/
public class AopAspectjTest {@Testpublic void smartDogTestByProxy() {//得到spring容器ApplicationContext ioc =new ClassPathXmlApplicationContext("beans08.xml");//这里我们需要通过接口类型来获取到注入的SmartDog对象-就是代理对象SmartAnimalable smartAnimalable =ioc.getBean(SmartAnimalable.class);//SmartAnimalable smartAnimalable =//        (SmartAnimalable)ioc.getBean("smartDog");smartAnimalable.getSum(10, 2);System.out.println("smartAnimalable运行类型="+ smartAnimalable.getClass());System.out.println("=============================");//smartAnimalable.getSub(100, 20);}@Testpublic void smartDogTestByProxy2() {//得到spring容器ApplicationContext ioc =new ClassPathXmlApplicationContext("beans08.xml");UsbInterface phone = (UsbInterface) ioc.getBean("phone");UsbInterface camera = (UsbInterface) ioc.getBean("camera");phone.work();System.out.println("==================");camera.work();}@Testpublic void test3() {//得到spring容器ApplicationContext ioc =new ClassPathXmlApplicationContext("beans08.xml");Car car = ioc.getBean(Car.class);//说明: car对象仍然是代理对象System.out.println("car的运行类型=" + car.getClass());car.run();}@Testpublic void testDoAround() {//得到spring容器ApplicationContext ioc =new ClassPathXmlApplicationContext("beans08.xml");SmartAnimalable smartAnimalable =ioc.getBean(SmartAnimalable.class);smartAnimalable.getSum(10, 2);}}

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

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

相关文章

通过http发送post请求的三种Content-Type分析

通过okhttp向服务端发起post网络请求,可以通过Content-Type设置发送请求数据的格式。 常用到的三种: 1)application/x-www-form-urlencoded; charsetutf-8 2)application/json; charsetutf-8 3)multipart/form-dat…

【论文阅读 09】融合门控自注意力机制的生成对抗网络视频异常检测

2021年 中国图象图形学报 摘 要 背景: 视频异常行为检测是智能监控技术的研究重点,广泛应用于社会安防领域。当前的挑战之一是如何提高异常检测的准确性,这需要有效地建模视频数据的空间维度和时间维度信息。生成对抗网络(GANs&…

后端大厂面试-16道面试题

1 java集合类有哪些? List是有序的Collection,使用此接口能够精确的控制每个元素的插入位置,用户能根据索引访问List中元素。常用的实现List的类有LinkedList,ArrayList,Vector,Stack。 ArrayList是容量…

2023 “华为杯” 中国研究生数学建模竞赛(D题)深度剖析|数学建模完整代码+建模过程全解全析

问题一:区域碳排放量以及经济、人口、能源消费量的现状分析 思路: 定义碳排放量 Prediction 模型: CO2 P * (GDP/P) * (E/GDP) * (CO2/E) 其中: CO2:碳排放量 P:人口数量 GDP/P:人均GDP E/GDP:单位GDP能耗 CO2/E:单位能耗碳排放量 2.收集并统计相关…

实现爬虫加速的可实现办法

网络爬虫在数据采集和信息监测中发挥着重要作用。然而,由于网络环境复杂和大量数据需求,爬虫速度可能面临挑战。本文将为您分享一些实现爬虫加速的可行方法,帮助您让爬虫快如闪电!让我们一起探索吧! 一、多线程并发请…

将 Ordinals 与比特币智能合约集成:第 2 部分

在上一篇文章中,我们展示了一种将 Ordinal 与智能合约集成的方法,即将Ordinal和合约放在同一个 UTXO 中。 今天,我们介绍了一种集成它们的替代方案,即它们位于单独的 UTXO 中。 作为展示,我们开发了一个智能合约&…

指针笔试题讲解-----让指针简单易懂(2)

目录 回顾上篇重点 : 一.笔试题 ( 1 ) 二.笔试题 ( 2 ) 科普进制知识点 (1) 二进制 (2) 八进制 (3)十六进制 三.笔试题( 3 ) 四.笔试题( 4 ) 五.笔试题( 5 ) 六.笔试题( …

在比特币上使用可检索性证明支付存储费用

我们为用户开发了一种为云存储付费的新方法。 与亚马逊的 S3 等传统云存储相比,用户不必信任服务器。 我们使用比特币智能合约来确保支付取决于服务器的可检索性证明 (PoR),该证明只能在数据仍然可用且需要时可以检索的情况下生成。 可检索性证明 (PoR)…

Java基础(一)——Hello World,8种数据类型,键盘录入

个人简介 👀个人主页: 前端杂货铺 🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…

FPGA — Vivado下ILA(逻辑分析仪)详细使用方法

使用软件: Vivado 开发板: EGO1采用Xilinx Artix-7系列XC7A35T-1CSG324C FPGA 使用程序:按键案例 ILA详细使用方法 一、ILA简介二、ILA的使用方法方法1 — 使用IP核创建ILA调试环境创建ILA IP核 方法二 — 使用 Debug 标记创建 ILA对需观察信…

中国核动力研究设计院使用 DolphinDB 替换 MySQL 实时监控仪表

随着仪表测点的大幅增多和采样频率的增加,中国核动力研究设计院仪控团队原本基于 MySQL 搭建的旧系统已经无法满足大量数据并发写入、实时查询和聚合计算的需求。他们在研究 DB-Engines 时序数据库榜单时了解到国内排名第一的 DolphinDB。经过测试,发现其…

【C++面向对象侯捷】8.栈,堆和内存管理

文章目录 栈,堆stack object的生命周期static local object的生命周期global object的生命周期heap objects 的生命期new:先分配memory,再调用构造函数delete: 先调用析构函数,再释放 memory动态分配所得的内存块,in V…

Vue系列(三)之 基础语法下篇【事件处理,表单综合案例,组件通信】

一. 事件处理 在 Vue.js 中,v-on 指令被用于监听 DOM 事件,并在事件触发时执行相应的方法,这些方法就是事件处理器。v-on 指令有简写形式 ,例如 click"handleClick" 会监听点击事件并执行 handleClick 方法。 事件处理…

CentOS 7 安装Libevent

CentOS 7 安装Libevent 1.下载安装包 新版本是libevent-2.1.12-stable.tar.gz。(如果你的系统已经安装了libevent,可以不用安装) 官网:http://www.monkey.org/~provos/libevent/ 2.创建目录 # mkdir libevent-stable 3.解压 …

pdf文件可以压缩大小吗?pdf压缩方法分享

在日常生活和工作中,我们经常需要处理大量的PDF文件。有时候,一个PDF文件的大小可能超过了几十MB,甚至无法通过电子邮件发送。那么,如何有效地压缩PDF文件大小呢?本文将为你介绍三个简单易行的方法,帮助你轻…

RabbitMQ工作模式——Topics模式

1.Topics通配符模式 *是一个单词,#是0到多个单词 Topics模式生产者代码 public class Producer_Topic {public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接工厂ConnectionFactory factory new ConnectionFactory();//…

FreeRTOS 任务创建分析

FreeRTOS 任务创建分析 Fang XS.1452512966qq.com如果有错误,希望被指出,学习技术的路难免会磕磕绊绊 FreeRTOS FreeRTOS快速上手教程FreeRTOS之任务优先级设置TCB 即任务控制块。FreeRTOS中使用TCB来进行任务管理,用来储存任务状态&#…

【C语言】指针笔试题解析

大家好,我是苏貝,本篇博客带大家了解指针和数组笔试题解析,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 1. 下面程序的结果是什么? int main() {int a[5] { 1, 2, 3, 4, 5 };i…

Nginx负载均衡详解

一、负载均衡介绍 1、负载均衡的定义 单体服务器解决不了并发量大的请求,所以,我们可以横向增加服务器的数量(集群),然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多…

React useRequest解读

源码结构: 可以看到虽然是一个hooks(具有一定功能且具备状态的单一函数) 但是各种文件功能分得也是很细的,方便抽离和复用 useRequest.ts 抽离的原则还是单一功能原则 可以看出 真正的hooks实现是在Implement里 对于类型type的引…