Spring的第十二阶段(01):Spring实现AOP的简单使用

news/2024/11/1 10:18:03/

1、使用Spring实现AOP简单切面编程

需要导入工程的jar包
Spring的核心包

spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar

Spring的测试包

spring-test-4.0.0.RELEASE.jar

Spring日记相关包

commons-logging-1.1.3.jar
log4j-1.2.17.jar

Spring的AOP切面相关的包

spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

需要有的类

public interface Calculate {public int add(int num1, int num2);public int mul(int num1, int num2);public int div(int num1, int num2);public int sub(int num1, int num2);
}@Component
public class Calculator implements Calculate {@Overridepublic int add(int num1, int num2) {return num1 + num2;}@Overridepublic int mul(int num1, int num2) {return num1 * num2;}@Overridepublic int div(int num1, int num2) {return num1 / num2;}@Overridepublic int sub(int num1, int num2) {return num1 - num2;}
}
@Aspect
@Component
public class LogUtil {@Before(value = "execution(public int com.atguigu.aop.Calculator.add(int, int))")public static void logBefore() {System.out.println("前置 日记 :【xxx】 方法调用前 。参数1是:xxxx");}@After(value = "execution(public int com.atguigu.aop.Calculator.add(int, int))")public static void logAfter() {System.out.println("后置 日记 :【xxxx】 方法调用前 。参数1是:xxxx");}@AfterReturning(value = "execution(public int com.atguigu.aop.Calculator.add(int, int))")public static void logAfterReturn() {System.out.println("返回之后: 日记 :【xxxxx】 方法调用前 。参数1是:xxxxxx");}@AfterThrowing(value = "execution(public int com.atguigu.aop.Calculator.add(int, int))")public static void logThrowException() {System.out.println("抛异常:日记 :【xxxxx】 方法调用前 。参数1是:xxxxxx");}}

applicationContext.xml配置文件中的内容

<context:component-scan base-package="com.atguigu" />
<aop:aspectj-autoproxy />

测试代码

@ContextConfiguration(locations = "classpath:applicationContext.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringAopTest {@Autowiredprivate Calculate calculate;@Testpublic void test1() {System.out.println( "添加:" + calculate.add(1, 2));}
}

测试运行的结果

在这里插入图片描述

2、Spring的切入点表达式

@PointCut切入点表达式语法格式是: execution(访问权限 返回值类型 方法全限定名(参数类型列表))

限定符:
*1)	匹配某全类名下,任意或多个方法。
表示匹配com.atguigu.aop.Calculator下以a打头的任意方法。并且返回值和两个参数都是int类型。
execution(public int com.atguigu.aop.Calculator.a*(int, int))表示匹配com.atguigu.aop.Calculator下的任意方法。并且返回值和两个参数都是int类型。
execution(public int com.atguigu.aop.Calculator.*(int, int))2)	在Spring中只有public权限能拦截到,访问权限可以省略(访问权限不能写*)。
// 权限省略,表示任意类型的访问权限 ,但Spring现在只支持public权限 
execution(int com.atguigu.aop.Calculator.*(int, int))3)	匹配任意类型的返回值,可以使用 * 表示
// 表示任意类型的返回值
execution(* com.atguigu.aop.Calculator.*(int, int))4)	匹配任意子包。
// 表示匹配com的子包
execution(* com.*.aop.Calculator.*(int, int))5)	任意类型参数
// 表示第二个参数是任意类型
execution(* com.atguigu.aop.Calculator.*(int,*))..:可以匹配多层路径,或任意多个任意类型参数
// 表示com和aop之间可以有任意层级的包
execution(* com..aop.Calculator.*(int,int))
// 表示第一个参数是int。之后可以有任意个任意类型的参数
execution(* com.atguigu.aop.Calculator.*(int,..))
模糊匹配:
// 表示任意返回值,任意方法全限定符,任意参数
execution(* *(..))
// 表示任意返回值,任意包名+任意方法名,任意参数
execution(* *.*(..))精确匹配:
// int 返回值,com.atguigu.aop.Calculator类的add方法,两个int参数
execution(public int com.atguigu.aop.Calculator.add(int, int))切入点表达式连接:&&|| 
// 表示需要同时满足两个表达式@Before("execution(public int com.atguigu.aop.Calculator.add(int, int))"+ " && "
+ "execution(public * com.atguigu.aop.Calculator.add(..))")// 表示两个条件只需要满足一个,就会被匹配到@Before("execution(public int com.atguigu.aop.Calculator.add(int, int))"+ " || "+ "execution(public * com.atguigu.aop.Calculator.a*(int))")

3、Spring切面中的代理对象

在Spring中,可以对有接口的对象和无接口的对象分别进行代理。在使用上有些细微的差别。

  1. 如果被代理的对象实现了接口。在获取对象的时候,必须要以接口来接收返回的对象。

测试的代码:
在这里插入图片描述
在这里插入图片描述

测试的结果:
在这里插入图片描述

  1. 被切面拦截的代理对象,如果没有实现接口。获取对象的时候使用对象类型本身
    在这里插入图片描述

测试的代码:
在这里插入图片描述

测试结果

在这里插入图片描述


http://www.ppmy.cn/news/60549.html

相关文章

《通过十几轮数据进行模型训练,实现精确的无创血糖测量的演绎学习》阅读笔记

目录 0 演绎学习 1 论文摘要 2 论文十问 3 论文亮点与不足之处 4 与其他研究的比较 5 实际应用与影响 6 个人思考与启示 参考文献 0 演绎学习 在本文中&#xff0c;DL指的是Deduction Learning&#xff0c;即演绎学习方法。该方法是一种机器学习方法&#xff0c;通过使…

Threejs进阶之十二:Threejs与Tween.js结合创建动画

tween.js介绍 Tween.js是一个可以产生平滑动画效果的js库&#xff0c;其官方地址为&#xff1a;https://github.com/tweenjs/tween.js/&#xff0c;可以将源码下载后&#xff0c;可以在tween.js/dist/文件夹下找到相应的js代码&#xff0c;在HTML中进行引用&#xff1b;也可以…

Docker Compose-模板文件说明

Compose 模板文件 模板文件是使用 Compose 的核心&#xff0c;涉及到的指令关键字比较多&#xff0c;这里面大部分指令跟 docker run 相关参数的含义都是类似的。 默认的模板文件名称为 docker-compose.yml&#xff0c;格式为 YAML 格式。 version: "3"services:w…

创新案例|香氛新品牌观夏如何以DTC模式仅4年实现年收过亿

国产香氛品牌观夏的DTC战略&#xff0c;正是从产品创新、全渠道布局、社交电商营销等方面创新&#xff0c;实现更高效地直接触达和转化消费者。观夏作为香氛DTC品牌的创新模式值得更多国内新品牌的关注与借鉴&#xff0c;同时也能为传统品牌的DTC转型提供全球化视野的启示。 1.…

改进YOLOv5: | 涨点神器 | 即插即用| ICLR 2022!Intel提出ODConv:即插即用的动态卷积

OMNI-DIMENSIONAL DYNAMIC CONVOLUTION ODConv实验核心代码ODConv代码yaml文件运行:论文链接: https://openreview.net/forum?id=DmpCfq6Mg39 本文介绍了一篇动态卷积的工作:ODConv,其通过并行策略采用多维注意力机制沿核空间的四个维度学习互补性注意力。作为一种“即插…

【C++】类和对象

目录 1. 类的定义 2. 访问限定符 3. 类对象模型 4. this指针 4.1 this指针的引入 4.2 this指针的特性 5. const成员函数 6. 构造、析构、拷贝构造 6.1 构造函数 6.1.1 构造函数的概念 6.1.2 初始化列表 6.1.3 构造函数的特性 6.1.4 explicit关键字 6.2 析构函数 …

【python】keras包:深度学习( MLP多层感知器 Multi-Layer Perceptron)

MLP多层感知器 Multi-Layer Perceptron Part 1. 算法逻辑 实现经典问题——如何通过图像区分猫和狗 神经网络&#xff1a;建立模型&#xff0c;模仿人的思考机制 将“机器学习_逻辑回归”按照神经元的逻辑&#xff0c;组成逻辑网络。 解释&#xff1a; 假设自变量x[]和应变…

【开发工具】 Office Tool Plus 居然也可以部署 Office 365 我的天 真的是太厉害了

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&#x1…