【第五章 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开发板部署手势检测数据集:本项目的数据集包括三种标签&…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...
上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式
简介 在我的 QT/C 开发工作中,合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式:工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...
