【第五章 AOP概述,底层原理,AOP术语,切入点表达式,AOP操作(基于注解方式,基于xml配置文件)】
第五章 AOP概述,底层原理,AOP术语,切入点表达式,AOP操作(基于注解方式,基于xml配置文件)
1.AOP概述:
(1)什么是AOP:
①面向切面编程(方面),利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分间的耦合度降低,提高程序的可重用性,同时提高开发的效率。
②通俗描述:不通过修改源代码方式,在主干功能里面添加新功能。
(2)底层原理:
①AOP底层使用动态代理:有两种情况动态代理。
第一种,有接口情况:使用jdk动态代理;
创建接口实现类代理对象,增强类的方法。
第二种,没有接口情况,使用CGLIB动态代理。
创建子类的代理对象,增强类的方法。
②AOP(jdk动态代理):
a.使用jdk动态代理,使用Proxy类里面的方法创建代理对象。
调用newProxyInstance方法
方法有三个参数:
第一个参数:类加载器。
第二个参数:增强方法所在类,这个类实现的接口,支持多个接口。
第三个参数:实现这个接口InvocationHandler,创建代理对象,写增强的方法。
b.编写jdk动态代理代码。
第一步:创建接口,定义方法;
public interface UserDao {public int add(int a,int b);public String update(String id);
}
第二步:创建接口实现类,实现方法;
public class UserDaoImpl implements UserDao {@Overridepublic int add(int a, int b) {System.out.println("add方法执行了");return a+b;}@Overridepublic String update(String id) {System.out.println("update方法执行了");return id;}
}
第三步:使用Proxy类创建接口代理对象;
public class JDKProxy {public static void main(String[] args) {//创建接口实现类代理对象Class[] interfaces={UserDao.class};UserDaoImpl userDao=new UserDaoImpl();UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao));int result = dao.add(1, 2);System.out.println("result"+result);}
}
//创建代理对象代码
class UserDaoProxy implements InvocationHandler{//把创建的是谁的代理对象,把谁传递过来//有参数的构造进行传递private Object obj;public UserDaoProxy( 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 res = method.invoke(obj, args);//方法之后System.out.println("在方法之后执行"+obj);return res;}
}
(3)AOP术语:
①连接点:类里面哪些方法可以被增强,这些方法称为连接点。
②切入点:实际被真正增强的方法,称为切入点。
③通知(增强):实际增强的逻辑部分称为通知(增强)
通知有多种类型:前置通知、后置通知、环绕通知、异常通知、最终通知(类似于try-catch中的finally)
④切面:把通知应用到切入点的过程。
2.AOP操作(准备工作):
(1)在spring框架中一般基于AspectJ实现AOP操作。
AspectJ:不是spring组成部分,独立AOP框架,一般把AspectJ和spring框架一起使用,进行AOP操作。
(2)基于AspectJ实现AOP操作。
①基于xml配置文件实现;
②基于注解方式实现。
(3)在项目中引入AOP依赖:
(4)切入点表达式:
①切入点表达式作用:知道要对哪个类里面的哪个方法进行增强。
②语法结构:
execution([权限修饰符] [返回类型] [类全路径名] [方法名称] [参数列表])
举例1:对demo1.dao.BookDao类里面的add进行增强
execution(* demo1.dao.BookDao.add(..))
举例2:对demo1.dao.BookDao类里面的所有方法进行增强
execution(* demo1.dao.BookDao.*(..))
举例3:对demo1.dao.包里面的所有类,类里面的所有方法进行增强
execution(* demo1.dao.*.*(..))
3.AOP操作(AspectJ 基于注解方式)
(1)创建类,在类里面定义方法;
//被增强类
public class User {public void add(){System.out.println("add......");}
}
(2)创建增强类,编写增强逻辑
①在增强类里面,创建方法,让不同的方法代表不同通知类型。
//增强类
public class UserProxy {//前置通知public void before(){System.out.println("before....");}
}
(3)进行通知的配置
①在spring配置文件中,开启注解的扫描
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><!--开启注解扫描--><context:component-scan base-package="aopano"></context:component-scan>
②使用注解创建User和UserProxy对象
@Component
public class User {}
@Component
public class UserProxy {}
③在增强类上面添加注解@Aspect
@Component
@Aspect
public class UserProxy {}
④在spring配置文件中开启生成代理对象
<!--开启Aspect生成代理对象--><aop:aspectj-autoproxy></aop:aspectj-autoproxy>
(4)配置不同类型的通知
①在增强类里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置
//增强类
@Component
@Aspect
public class UserProxy {//前置通知@Before(value = "execution(* aopano.User.add(..))")public void before(){System.out.println("before....");}
}
测试的时候执行的是被增强的方法@Testpublic void testAopno(){ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean2.xml");User user = applicationContext.getBean("user", User.class);user.add();}

//前置通知@Before(value = "execution(* aopano.User.add(..))")public void before(){System.out.println("before....");}//最终通知@After(value = "execution(* aopano.User.add(..))")public void after(){System.out.println("after....");}//后置通知@AfterReturning(value = "execution(* aopano.User.add(..))")public void afterReturning(){System.out.println("afterReturning....");}//异常通知@AfterThrowing(value = "execution(* aopano.User.add(..))")public void afterThrowing(){System.out.println("afterThrowing....");}//环绕通知@Around(value = "execution(* aopano.User.add(..))")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("环绕之前");//被增强的方法执行proceedingJoinPoint.proceed();System.out.println("环绕之后");}
(5)公共切入点进行抽取:
//相同切入点进行抽取@Pointcut(value = "execution(* aopano.User.add(..))")public void pointdemo(){}//前置通知@Before(value = "pointdemo()")public void before(){System.out.println("before....");}
(6)有多个增强类对同一个方法进行增强,设置增强类优先级。
在增强类的上面添加注解@Order(数字类型值),数字类型值越小,优先级越高。
@Component
@Aspect
@Order(1)
public class personProxy {@Before(value = "execution(* aopano.User.add(..))")public void afterReturning(){System.out.println("person before ....");}
}
4.AOP操作(AspectJ 基于xml配置文件方式)(了解)
(1)创建两个类,增强类和被增强类,创建方法;
public class Book {public void buy(){System.out.println("buy.....");}
}
public class BookProxy {public void before(){System.out.println("before....");}
}
(2)在spring配置文件中创建两个类对象;
<!--创建两个类的对象--><bean id="book" class="aopxml.Book"></bean><bean id="bookProxy" class="aopxml.BookProxy"></bean>
(3)在spring配置文件中配置切入点。
<!--aop的增强--><aop:config ><!--切入点--><aop:pointcut id="p" expression="execution(* aopxml.Book.buy(..))"/><!--配置切面--><aop:aspect ref="bookProxy"><!--增强作用在具体的方法上--><aop:before method="before" pointcut-ref="p"></aop:before></aop:aspect></aop:config>
相关文章:
【第五章 AOP概述,底层原理,AOP术语,切入点表达式,AOP操作(基于注解方式,基于xml配置文件)】
第五章 AOP概述,底层原理,AOP术语,切入点表达式,AOP操作(基于注解方式,基于xml配置文件) 1.AOP概述: (1)什么是AOP: ①面向切面编程(…...
面试官: 你知道 JWT、JWE、JWS 、JWK嘛?
想起了 之前做过的 很多 登录授权 的项目 它相比原先的session、cookie来说,更快更安全,跨域也不再是问题,更关键的是更加优雅 ,所以今天总结了一篇文章来介绍他 JWT 指JSON Web Token,如果在项目中通过 jjwt 来支持 J…...
基于企业微信应用消息的每日早安推送
基于企业微信应用消息的每日早安推送 第一步:注册企业微信 企业微信注册地址:https://work.weixin.qq.com/wework_admin/register_wx 按照正常流程填写信息即可,个人也可以注册企业微信,不需要公司 注册完成后,登录…...
【数字IC基础】黑盒验证、白盒验证、 灰盒验证
文章目录 一、黑盒验证二、白盒验证三、灰盒验证一、黑盒验证 1、黑盒验证:大多数基于仿真的验证环境都是黑盒验证;2、不需要知道设计的内部结构和特性,只需要在输入端口打激励,观察输出即可;3、验证工程师学习设计的规格,然后编写验证环境中的 drivers, monitors, check…...
管理的本质是达成目标
“没有目标,其实就没有管理学存在的意义。要有效地使用管理学的智慧,首先要建立清晰的目标。” - 《宁向东的管理学课》 起源 最近开始刷很久之前就在得到上买了的已经起灰了的课程,看到这句话觉得很有道理。 思考 这里面有一个很重要的词…...
【数字IC基础】IC(Integrated Circuit,集成电路)常用缩写
文章目录 1、集成电路:2、数字IC设计相关步骤:3、数字设计相关概念:4、验证相关:5、语言类:6、IC设计相关工具:7、存储器相关:8、总线协议类:9、文件格式类:10、标准和规范:11、其它:1、集成电路: 缩写全称中文翻译LSILarge-scale intergrated circuit大规模集成电…...
JavaScript 高级1 :面向对象
JavaScript 高级1 :面向对象 Date: January 16, 2023 Text: 面向对象、ES6中类和对象、类的继承、面向对象案例 目标: 能够说出什么是面向对象 能够说出类和对象的关系 能够使用 class 创建自定义类型 能够说出什么是继承 面向对象编程介绍 面向过…...
C语言结构体对齐
1. 结构体对齐 要点 变量只能存储在他的长度的整数倍地址上结构体整体对齐跟他的最长的字段整数倍对齐 栗子1 struct Example1 {char a; //1个字节int c; //4个字节short b; //2个字节 };std::cout << sizeof(Example1 ) << std::endl; // 12 std::cout &…...
Bootstrap系列之导航
Bootstrap导航 可以在 ul 元素上添加 .nav类,在每个 li 选项上添加 .nav-item 类,在每个链接上添加 .nav-link 类: 基本的导航 <div class"container mt-3"><h2>导航</h2><p>简单的水平导航:</p><ul class&…...
Java EE|TCP/IP协议栈之应用层协议DNS详解
文章目录一、对DNS的感性认识简介特点一些常见疑问二、DNSDNS域名结构域名的分级三、域名服务器四、域名解析过程参考一、对DNS的感性认识 简介 DNS,即Domain Name System,是域名系统的简称。它是Internet上解决网上机器命名的一种系统。 TCP/IP中的IP地址是由四…...
【MyBatis】作用域生命周期(四)
🚗MyBatis学习第四站~ 🚩起始站:MyBatis概述&环境搭建(一) 🚩本文已收录至专栏:数据库学习之旅 👍希望您能有所收获 一.引入 为了使用方便,我们经常能看到各种教程都将MyBatis抽离为工具类…...
腾讯一面—Android 系统启动流程详解
正文AMS 是 Android 中最核心的服务之一,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块相类似,它本身也是一个 Binder 的实现类,应用进程能通过 Binder 机制调用…...
【Python知识点桂电版】02组合数据类型
一、序列序列简介序列是指一种包含多项数据的数据结构,分为不可变序列和可变序列。可变序列可修改序列内的元素如列表,二不可变序列一旦建立就不能修改其中的元素,字符串和元组属于不可变序列。列表和元组的创建列表:列表名 [元素…...
LeetCode100_100. 相同的树
LeetCode100_100. 相同的树 一、描述 给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 示例 1: 输入:p [1,2,3], q […...
javaEE 初阶 — 网络层中 IP 协议 的报文结构
文章目录IP 协议报文4位版本号4位首部长度8位服务类型16位总长度(字节数)8位生存时间(TTL)与 8位协议16位首部校验和32位源 IP 地址与32位目标 IP 地址动态分配的 IP 地址NAT 网络地址转换IPv6IP 协议报文 4位版本号 这里的 IP 协…...
iOS swift UICollectionView
文章目录1.纯代码自定义UICollectionViewCell2.禁止滑动(弹簧效果)3.UICollectionView的长按拖动2.在一个控制器中放两个UICollectionView或者UITableView,代理方法要怎么写1.纯代码自定义UICollectionViewCell import UIKitclass NewDeviceBottomColle…...
计算机三级数据库 填空题汇总
计算机三级 数据库 IDEF0需求建模方法由箭头和(活动/方框/矩形)两种元素构成。、从安全性角度考虑,防火墙技术是用来保证数据库应用系统的(网络)环境安全的。在UML的状态机图中,状态之间的转移是由&#x…...
【Java学习】初识Java
JavaSEJava初识1. Java简介2.Java环境的安装与配置3. 开发第一个Java程序Java初识 学前疑问:(带着疑问去学习,在学习中自行探索答案) Java是什么?能做什么?发展前景如何?需要学习哪些内容&…...
LabVIEW网络服务安全
LabVIEW网络服务安全如何保护Web服务?当许多人考虑安全性时,他们会考虑加密、用户ID和密码。用户ID和密码用于授权(告诉目标谁在发出请求)。加密保护客户端和服务器之间的通信流量,以便未经授权的个人无法拦截和读取发…...
基于MaixBit(K210芯片)的图像识别猜拳手势博弈装置
本文介绍了一种基于嵌入式平台开发的图像识别部署装置,其主要功能包括实现机器与人的“猜拳博弈”,其组成分为三个部分:手势检测数据集图像识别模型训练模型格式部署maixbit开发板部署手势检测数据集:本项目的数据集包括三种标签&…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙
WebGL:在浏览器中解锁3D世界的魔法钥匙 引言:网页的边界正在消失 在数字化浪潮的推动下,网页早已不再是静态信息的展示窗口。如今,我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室,甚至沉浸式的V…...
