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.xdnf.cn/news/141636.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【C++笔记】C++ list类模拟实现

【C笔记】C list类模拟实现 一、初始化和各种构造1.1、准备工作1.2、各种构造和析构 二、插入和删除2.1、插入2.2、删除 三、迭代器3.1、正向迭代器3.2、反向迭代器3.3、提供迭代器位置 四、其他一些接口4.1、链表的长度和判空4.2、返回链表的头尾结点 一、初始化和各种构造 C…

李宏毅hw-10 ——adversarial attack

一、查漏补缺: 1.关于glob.glob的用法,返回一个文件路径的 列表: 当然,再套用1个sort,就是将所有的文件路径按照字母进行排序了 2.relpath relative_path返回相对于基准路径的相对路径的函数 二、代码剖析&#xff…

【红帽】跟着学习如何使用桌面访问命令行

今天我们分享一些红帽Linux的知识,记得关注,会一直更新~ ▶1、以student用户身份并使用student作为密码登录workstation 1.1.在workstation上,从GNOME登录屏幕中单击student用户帐户。系统提示输入密码时,请输入student。 1.2.…

JavaScript系列从入门到精通系列第九篇:JavaScript中赋值运算符和关系运算符以及Unicode编码介绍

一:赋值运算符 1: 右侧的值可以赋值给左侧的变量。 var a 123; console.log(a);//123 2: var a 10; a a 5; a 5; 上边这两个写法是一样的。 3:- var a 10; a a-5; a - 5; 上边这两个写法是一样的。 4:* …

数据备份文件生成--根据表名生成对应的sql语句文件

最近客户有个需求,希望在后台增加手动备份功能,将数据导出下载保存。 当然,此方法不适用于海量数据的备份,这只适用于少量数据的sql备份。 这是我生成的sql文件,以及sql文件里的insert语句,已亲测&#x…

Java抽象类、接口

1.抽象类 1.abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类那么该类就是抽象类。2.抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类3.抽象类,不能使用new关键字来创建对象,它是用来让子类继承的4.抽象方法,只有…

接口测试入门

1. 什么是接口测试 顾名思义,接口测试是对系统或组件之间的接口进行测试,主要是校验数据的交换,传递和控制管理过程,以及相互逻辑依赖关系。其中接口协议分为HTTP,WebService,Dubbo,Thrift,Socket等类型,测试类型又主…

nodejs 如何在npm发布自己的包 <记录>

一、包结构 必要结构: 一个包对应一个文件夹(文件夹名不是包名,但最好与包名保持一致,包名以package.json中的name为主)包的入口文件index.js包的配置文件package.json包的说明文档README.md 二、需要说明的文件 1.配…

【密码学补充知识】

🔑密码学🔒概述 📕 1.基本概念 明文 : 要交换的信息 密文 : 明文经过一组规则变换成看似没有意义的随机消息。 加密 : 明文经过一组规则变换成密文的过程 解密 : 密文恢复出明文的过程 加…

基于 MATLAB 的电力系统动态分析研究【IEEE9、IEEE68系节点】

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

linux-如何用起来ubuntu

1 Oracle VM VirtualBox安装ubuntu20.04虚拟机 【工具】->【新建】 1.1 虚拟电脑名称和系统类型 【名称】:自定义名称即可 【文件夹】:虚拟机文件将要存储的路径 【虚拟光盘】:将要安装的虚拟机iso文件 1.2 自动安装 【用户名】&…

uniapp:tabBar点击后设置动画效果

APP端不支持dom操作,也不支持active伪类,绞尽脑汁也没办法给uniapp原生的tabBar点击加动画效果,所以最终只能舍弃原生tabBar,改用自定义tabBar。 自定义tabBar的原理是,页面的上部分分别是tabBar对应的页面组件&#…

什么是Selenium?使用Selenium进行自动化测试!

你知道什么是 Selenium 吗?你知道为什么要使用它吗?答案就在本文中,很高兴能够与你共飧。 自动化测试正席卷全球,Selenium 认证是业界最抢手的技能之一。 什么是 Selenium? Selenium 是一种开源工具,用于…

400电话申请流程详解,助您快速办理联通、移动、电信400电话

导语:随着企业业务的发展,越来越多的企业开始关注400电话的申请与办理。本文将为您详细介绍联通、移动、电信400电话的申请流程,帮助您快速办理400电话,提升企业形象和客户服务质量。 一、联通400电话申请流程 咨询与选择&#x…

孤网双机并联逆变器下垂控制策略MATLAB仿真模型

微❤关注“电气仔推送”获得资料 主体模块: 建议使用MATLAB2021b及以上版本打开! 功率计算模块、下垂控制模块、电压电流双环控制模块 系统输出有功功率: 系统输出无功功率: 系统频率变化曲线: 参考文献: 微电网并网运行模式下…

arcgis搭建离线地图服务WMTS

Arcgis搭建离线地图服务WMTS 发布时间:2021-03-04 版权: ARCGIS搭建离线地图服务器,进行离线地图二次开发 2. 离线地图服务发布(WMTS服务) (详细教程:卫星地图_高清卫星地图_地图编辑_离线地…

数据结构上机1

1、题目&#xff1a; 将1~10存入数组a[10]&#xff0c;并将其逆序输出 #define _CRT_SECURE_NO_WARNINGS 1 //(1) 将1~10存入数组a[10]&#xff0c;并将其逆序输出#include <stdio.h>int main() {int a[10];// 将1到10存入数组a[10]for (int i 0; i < 10; i){a[i] i…

Day 02 python学习笔记

python运算符 算术运算符 混合运算的优先级&#xff1a; () 高于 ** * / // % 高于 - 赋值运算符 - * / ** a 1 > a 3 > a a 3 其余同理 注意&#xff1a; python没有自增自减 &#xff08;a a a-- --a&#xff09;…

ad18学习笔记十一:显示和隐藏网络、铺铜

如何显示和隐藏网络&#xff1f; Altium Designer--如何快速查看PCB网络布线_ad原理图查看某一网络的走线_辉_0527的博客-CSDN博客 AD19(Altium Designer)如何显示和隐藏网络 如何显示和隐藏铺铜&#xff1f; Altium Designer 20在PCB中显示或隐藏每层铺铜-百度经验 AD打开与…

404. 左叶子之和

给定二叉树的根节点 root &#xff0c;返回所有左叶子之和。 示例 1&#xff1a; 输入: root [3,9,20,null,null,15,7] 输出: 24 解释: 在这个二叉树中&#xff0c;有两个左叶子&#xff0c;分别是 9 和 15&#xff0c;所以返回 24示例 2: 输入: root [1] 输出: 0 //bfs …