11-13 /11-14代理模式 AOP

调用者 代理对象 目标对象

代理对象除了可以完成核心任务,还可以增强其他任务,无感的增强

代理模式目的:
不改变目标对象的目标方法的前提,去增强目标方法

分为:静态代理,动态代理


静态代理

有对象->前提需要有一个类,那么我们可以事先写好一个类,他是一个代理类

程序员为目标类编写一个代理类(用于增强目标方法),要求目标类和代理类实现同一个接口,让用户感觉代理和目标是一类的东西,无感的

创建一个maven

创包com.fs.staticproxy

创目标类和代理类的统一接口:

创建目标类:

目标方法之前可能需要扩展 日志记录 权限管理等等  这些不是非核心代码、功能,可能就是一些简单的业务,但是又不省略,但是他又不是固定的,时可变的,而卸载目标类就是硬代码

 创建代理类:代理代理 -> 我中有你  有一个目标对象

出现问题:重复

解决办法:我(代理类)中有(目标类)你

给属性复赋值:构造方法 set方法 实现了代理类增强方法

测试类(调用者):

需要改变时,目标对象、目标类不需要改变,核心代码不用改变,,只需要改代理对象

缺点:多个接口要实现相同的方法,增强相同的方法,那么需要创建很多个代理类,这是不对的,

核心接口加方法,代理类也要加方法实现对应的方法,目标对象和代理类都需要维护

导致静态代理的缺点问题根源->代理类的存在

动态代理

这个静态代理类不要你写,通过code动态生成

存的是BussinessInterface接口  -> 使得这个代理类代理的范围更加多一点,不再只有Buiness这一个实现类的代理类,他可以实现只要你的目标类实现BussinessInterface这一类   统一接口下面所有的不同类型的这个目标类都可以被我的代理类所代理

站在使用者这边,我们在乎的是代理类对象,而不是代理类,基于这个,

jdk可以自动生成生成这个代理类对象,确实可以实现,我要代哪一个接口,接口告诉我,然后jdk有一个api方法,经过这个api方法的时候,他就可以得到一个api代理对象,此时我就不需要代理类了,我直接用这个代理对象就行了

通过接口的class对象,创建一个实现类的Class对象,再通过反射得到实现类的对象(这个实现类是动态的,创建的是不存在的实现类对象)

jdk提供了通过接口的Class对象,创建一个实现类(动态,不存在)的Class对象的API:java.lang.reflect .Proxy类:

Proxy提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。以class造class

接口不能创建方法,因为它没有构造方法(用于创建对象),,现在想创建对象,

根据接口的创建对象,没有这个类,没有这个构造方法,也可以通过反射得到对象,通过反射得到Class对象,调用它的构造方法得到对象

我们现在需要一个类 class  由于接口不能创建构造方法,所以我们需要根据接口的class来克隆/生成一个类的class,这个类的classs是构造方法的class根据  根据接口的class对象生成类的class对象,这个类的class对象复制了接口的所有的方法,同时他又有构造方法。

创建对象的核心:前提条件就是要有该类的Class对象,(也可以通过new的方式去拿)拿到之后我么就可以通过反射创建对象,当然底层还是调用构造方法,比如接口类没有构造方法就无法创建对象

动态代理(基于接口)

创一个类:

$ -> 动态类

Class Proxy.getProxyClass(),得到Class对象对应类是Proxy的子类,而且得到Class对应类的模版参考Proxy类

Proxy的构造方法

子类构造方法(由于父类构造方法私有,不能调用父类构造方法)

父类只提供给这个有参构造方法:

$Proxy4:生成一个如下构造方法  虽然是受保护类型,但是

 (上面做了,通过接口的class对象构造代理类的实现对象)

 代理对象执行目标方法他会在底层调用invoke()方法

只要我在invoke写核心code 那么我就可以重写excute的逻辑code

为什么代理对象执行目标方法,底层还调用lnvocationHandler的invoke()?

为什么还要proxy.excute()和invoke()分开呢?

当我们使用动态代理时,代理对象执行目标方法时底层还调用`InvocationHandler`的`invoke()`方法是因为代理对象并不知道具体要执行的目标方法是什么,以及是否需要添加额外的逻辑。因此,代理对象将目标方法的调用委托给了`InvocationHandler`来处理。

代理对象在执行目标方法时,会将目标方法的信息(包括方法名、参数等)传递给`InvocationHandler`的`invoke()`方法。`InvocationHandler`可以根据这些信息进行额外的操作,比如在方法调用前后进行日志记录、权限验证等。

为什么还要将`proxy.execute()`和`invoke()`分开呢?这是因为动态代理的实现是通过`Proxy`类和`InvocationHandler`接口来配合完成的。`Proxy`类负责生成代理对象,而`InvocationHandler`接口负责处理方法调用。

`Proxy`类生成的代理对象并不直接实现目标接口的方法,而是在代理对象的方法中调用`InvocationHandler`的`invoke()`方法。这样的设计可以将代理对象的方法和`InvocationHandler`的逻辑分离,使得代理对象可以专注于代理的行为,而不需要关心具体的方法实现。

通过将方法调用和逻辑处理分开,我们可以更灵活地控制代理对象的行为。可以在`InvocationHandler`的`invoke()`方法中添加额外的逻辑,也可以根据需要选择不同的`InvocationHandler`实现,实现动态切换和扩展代理对象的功能。

总结来说,代理对象执行目标方法时底层还调用`InvocationHandler`的`invoke()`方法是为了将方法调用和逻辑处理分离,以实现更灵活的代理行为。这样的设计使得代理对象可以专注于代理行为,而不需要关心具体的方法实现。同时,通过分离方法调用和逻辑处理,我们可以实现更高级的代理功能,如动态切换代理行为或添加额外的逻辑。

proxy.excute();//但是没看到它重写的代码 

匿名类部类

lamba表达式(jdk8)

动态代理:  getMappper使用的动态代理

传接口的class对象,得到的是接口的实现类对象,再得到构造方法,再new instance得到实例对象

得到实现类的构造方法

得到接口的实现类对象之后,再实现代理

替换之前写的

  Proxy类得到接口的代理类对象,并且还需要对接口的抽象方法进行重写,写在invotionHandler接口对象的invoke()当中

问题: Proxy类得到接口的代理类对象,并且还需要对接口的抽象方法进行重写,重写方法的逻辑代码,在lnvocationHandler接口对象的invoke0中
Proxy:创建代理对象
lnvocationHandler接口对象的invoke()对方法重写的

为了创建代理对象与编写方法逻辑代码方法体分离,解耦
我们在创建代理对象的时候,可以不实现方法体,在后期根据你实际需求,传递方法体

开始代理

此时只能指定代理指定的代理类对象

现在改一改

对任何接口的目标类进行增强

所有:

对他增强

proxy.fun();

实现增强

配置文件优化,把增强代码出来,分离,形成一个增强类,

jdk实现的动态代理要求目标类一定要实现接口,所以这也是一个其动态代理的一个缺点所在

第二种方式:

使用第三方的CGLIB,它生成的代理类,这个类会继承目标类,所以他不会管这个目标类有没有实现接口,但是它要i求不能实现fina关键字(继承不能)

jdk自带的动态管理,要求目标类一定要实现接口,没有实现接口那么就是用CGLIB,记得不要使用final关键字就行了

动态代理的优点

优点:

1.没有代理类,解决静态代理的代理类暴增的问题

2.解决了静态代理的重复代码问题

3.创建代理对象与重写方法逻辑代码解耦

缺点:

增强代码与目标方法是通过硬编码的方式组织在一起,如果需要动态生成增强代码,需要修改代码

SpringAop

AOP:面向切面编程,对OOP的补充。不改变目标方法代码前提,增强目标方法

横切面:切面 目标方法/目标类->独立  增强类/增强方法->独立  两者独立,目标类前后都有

增强类/增强方法 但是在运行的时候,通过AOP或者其他技术,感觉这三个玩意是一起的,面向横切面

OOP:面向对象编程

userSer。。。  只要写目标类的核心代码  配置/注解的时候

AOP使用场景:

  • 事务控制 下单流程(生成订单insert 支付状态update 商品库存数量update)
  • 日志记录 (log4j) (开发中的日志表,记录用户行为信息)
  • 权限控制
  • 性能分析
  • 缓存操作        (实际缓存是基于Redis的技术)

Spring两大核心

  • IOC/DI:依赖对象之间的解耦
  • AOP:目标类与增强类的解耦   关注的是横切面的一个解耦

        AOP采取横向抽取机制((动态代理),取代了传统纵向继承机制的重复性代码,其应用主要体现在事务处理、日志管理、权限控制、异常处理等方面。
        主要作用是分离功能性需求和非功能性需求,使开发人员可以集中处理某一个关注点或者横切逻辑,减少对业务代码的侵入,增强代码的可读性和可维护性。
        简单的说,AOP的作用就是保证开发者在不修改源代码的前提下,为系统中的业务组件添加某种通用功能

SpringAOP开始使用

基于AspectJ这个AOP实现的

2.编写目标类目标方法

3.编写增强类(通知类)中增强方法

基于AspectJ方式,对增强类没有任何要求,就是一个普通类

增强:

        前置增强

        后置增强

        最终增强

        日志增强

        ......

4.织入,把目标方法与增强方法编织在一起,Spring提供AOP提供相关配置和注解

通过配置之后,这个before方法先于目标方法执行

delete没有实现增强代码功能

对这个包及子包

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

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

相关文章

【Mycat2实战】三、Mycat实现读写分离

1. 无聊的理论知识 什么是读写分离 读写分离,基本的原理是让主数据库处理事务性增、改、删操作, 而从数据库处理查询操作。 为什么使用读写分离 从集中到分布,最基本的一个需求不是数据存储的瓶颈,而是在于计算的瓶颈&#xff…

汽配零件发FBA美国专线

随着电商的迅速发展,跨境电商平台如亚马逊的FBA(Fulfillment by Amazon)服务成为了许多商家选择的销售渠道。对于汽配零件行业来说,发FBA美国专线可以打开更广阔的市场,并且有望获得可观的发展前景。下面将从市场分析和前景两个方面来探讨汽配…

pyTorch Hub 系列#2:VGG 和 ResNet

一、说明 在上一篇教程中,我们了解了 Torch Hub 背后的本质及其概念。然后,我们使用 Torch Hub 的复杂性发布了我们的模型,并通过相同的方式访问它。但是,当我们的工作要求我们利用 Torch Hub 上提供的众多全能模型之一时,会发生什么? 在本教程中,我们将学习如何利用称为…

[NSSRound#7 Team]ShadowFlag

文章目录 前置知识/proc目录python的反弹shellpin码计算 解题步骤 前置知识 /proc目录 Linux系统上的/proc目录是一种文件系统,用户可以通过这些文件查看有关系统硬件及当前正在运行进程的信息,甚至可以通过更改其中某些文件来改变内核的运行状态。/pro…

漏电继电器 LLJ-250HT AC220V 50-500ma 面板安装

系列型号: LLJ-10H(S)漏电继电器LLJ-15H(S)漏电继电器LLJ-16H(S)漏电继电器 LLJ-25H(S)漏电继电器LLJ-30H(S)漏电继电器LLJ-32H(S)漏电继电器 LLJ-60H(S)漏电继电器LLJ-63H(S)漏电继电器LLJ-80H(S)漏电继电器 LLJ-100H(S)漏电继电器LLJ-120H(S)漏电继电器LLJ-125H(…

深度学习 机器视觉 人脸识别系统 - opencv python 计算机竞赛

文章目录 0 前言1 机器学习-人脸识别过程人脸检测人脸对其人脸特征向量化人脸识别 2 深度学习-人脸识别过程人脸检测人脸识别Metric Larning 3 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习 机器视觉 人脸识别系统 该项目…

等保到底在“保”什么?

在信息时代,等保评级成为衡量企业信息安全水平的重要标准。那么,什么是等保评级呢?等保合规到底保的是什么呢?一起来看看吧。 编辑搜图 请点击输入图片描述(最多18字) 等保评级,会从七个维度进…

03-CSS基础选择器

3.1 CSS基础认知&#x1f34e; 3.1.1 &#x1f441;️‍&#x1f5e8;️CSS概念 CSS&#xff1a;层叠样式表&#xff08;Cascading style sheets)&#xff0c;为网页标签增加样式表现的 语法格式&#xff1a; 选择器{<!-- 属性设置 -->属性名:属性值; <!--每一个…

从0到0.01入门React | 004.精选 React 面试题

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

《QT从基础到进阶·二十八》QProcess使用,从一个exe程序启动另一个exe程序

QString exePath QCoreApplication::applicationDirPath(); //获取要启动的另一个exe路径 exePath exePath “/OffLineProcess.exe”; //路径exe名称 QProcess* Process new QProcess; //创建新的进程 Process->start(exePath)…

Dart利用私有构造函数_()创建单例模式

文章目录 类的构造函数_()函数dart中构造函数定义 类的构造函数 类的构造函数有两种&#xff1a; 1&#xff09;默认构造函数&#xff1a; 当实例化对象的时候&#xff0c;会自动调用的函数&#xff0c;构造函数的名称和类的名称相同&#xff0c;在一个类中默认构造函数只能由…

Copliot:让你一秒变身网页达人的神奇助手

Copliot&#xff1a;一款能够帮助你快速理解网页内容的智能助手 你是否有过这样的经历&#xff0c;当你浏览网页时&#xff0c;遇到了一些你不太了解的内容&#xff0c;比如一些专业术语&#xff0c;一些复杂的概念&#xff0c;或者一些有趣的话题&#xff1f;你是否想要快速地…

代码随想录 Day44 动规12 LeetCode T300 最长递增子序列 T674 最长连续递增序列 T718 最长重复子数组

前言 本期我们来解决动规的经典题型------ 子数组问题 我们还是会使用动规五部曲来解决问题,下面我们仍然列出动规五部曲 1.明确dp数组含义 2.明确dp数组如何推导-递推公式 3.初始化dp数组 4.确定遍历顺序 5.打印dp数组排错 LeetCode T300 最长递增子序列 题目链接:300. 最长…

git分支管理以及不同git工作流对比

0、 单人开发场景 单人开发可能会出现的场景之一 如果多人协同开发我们则需要使用更加专业的工具Git&#xff08;分布式版本控制&#xff09; 1、多人协同工作使用git会出现什么问题? 代码冲突&#xff1a; 问题&#xff1a; 当多个开发者同时修改同一文件或同一行代码时…

SQL编写规范【干货】

编写本文档的目的是保证在开发过程中产出高效、格式统一、易阅读、易维护的SQL代码。 1 编写目 2 SQL书写规范 3 SQL编写原则 获取所有软件开发资料&#xff1a;点我获取

TikTok女性创作者:媒体世界的新领袖

在数字时代&#xff0c;社交媒体已成为媒体和娱乐产业的关键组成部分&#xff0c;而TikTok作为最受欢迎的短视频分享平台之一&#xff0c;为女性创作者提供了一个独特的机会来在媒体世界中崭露头角。 这个平台不仅为女性创作者提供了一个创作和分享自己的声音、观点和创意的空…

Vue3中使用provide和inject依赖注入完成父组件和孙子组件之间参数传递

Vue3中使用provide和inject依赖注入完成父组件和孙子组件之间参数传递 官网介绍 注意以下写法都是使用setup 代码结构 依赖注入-父组件 import { ref, provide } from "vue"const outDialogCardInfo ref() function updateOutDialogCardInfo(item) {console.log…

初认识vue,v-for,v-if,v-bind,v-model,v-html等指令

vue 一.vue3介绍 1.为什么data是函数而不是对象? 因为vue是组件开发,组件会多次复用,data如果是对象,多次复用是共享,必须函数返回一个新的对象 1. 官网初识 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS …

【中间件篇-Redis缓存数据库07】Redis缓存使用问题及互联网运用

Redis缓存使用问题 数据一致性 只要使用到缓存&#xff0c;无论是本地内存做缓存还是使用 redis 做缓存&#xff0c;那么就会存在数据同步的问题。 我以 Tomcat 向 MySQL 中写入和删改数据为例&#xff0c;来给你解释一下&#xff0c;数据的增删改操作具体是如何进行的。 我…

C# DirectoryInfo类的用法

在C#中&#xff0c;DirectoryInfo类是System.IO命名空间中的一个类&#xff0c;用于操作文件夹&#xff08;目录&#xff09;。通过DirectoryInfo类&#xff0c;我们可以方便地创建、删除、移动和枚举文件夹。本文将详细介绍DirectoryInfo类的常用方法和属性&#xff0c;并提供…