Spring底层原理学习笔记--第十一讲--(aop之proxy增强-jdk及aop之proxy增强-cglib)

AOP实现之proxy

  • 1.jdk动态代理实现及要点

  • 2.cglib代理实现及要点

    invoke与invokeSuper区别

jdk动态代理实现及要点

package com.lucifer.itheima.a12;import java.lang.reflect.Proxy;public class JdkProxyDemo {interface Foo{void foo();}//该类可以设置成final类型 //jdk中的代理跟目标是平级的兄弟关系,他们都实现了共同的接口static class Target implements Foo{public void foo(){System.out.println("target foo");}}//jdk只能对接口代理//cglib 没有限制,可以对接口代理,如果没有接口的话也可以public static void main(String[] param) {
//        ClassLoader loader = JdkProxyDemo.class.getClassLoader();  // 用来加载在运行期间动态生成的字节码
//        //ClassLoader的作用:
//        // 代理类跟普通类有一个差别,普通类是先写java源代码,java源代码编译成java字节码,最后经过类加载然后可以使用
//        // 而代理类没有源码,它是在运行期间,直接生成代理类的字节码,生成后的字节码也要被加载后才能运行,谁来做这个操作呢,由我们的Classloader来做这个操作
//        //所以类加载器主要是用于加载代理类内部生成的字节码
//
//        Foo proxy = (Foo)Proxy.newProxyInstance(loader, new Class[] { Foo.class }, (p, method, args) -> {
//            System.out.println("before...");
//            return null;
//        });
//
//        //参数二
//        // 将来要生成的代理,要实现的是哪个接口
//        // 参数三是干什么的,大家想代理类创建出来了,它也实现了我们的接口,它要实现接口中的抽象方法,必须规定这些方法的行为,那谁来把这些行为进行封装呢,就是第三个参数来做的
//
//        //总结:参数1: 用来加载在运行期间动态生成的字节码
//        //参数2:将来要实现的接口
//        //参数3:代理类调用任何代理方法时,要执行的一些行为
//
//
//        //输出结果为
        before...
//        proxy.foo();//目标对象Target target = new Target();ClassLoader loader = JdkProxyDemo.class.getClassLoader();   //用来加载在运行期间动态生成的字节码Foo proxy = (Foo)Proxy.newProxyInstance(loader,new Class[]{Foo.class},(p,method,args) -> {System.out.println("before...");//目标.方法(参数)//方法.invoke(目标,参数)Object result = method.invoke(target,args);System.out.println("after...");return result;       //让代理也返回目标方法执行的结果});//        //输出结果为
//        before...
//        target foo
//        after...proxy.foo();}
}

cglib代理实现及要点

package com.lucifer.itheima.a12;import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;public class CglibProxyDemo {// 该类不能设置成final类型  因为目标加了final 意味着将来不能有子类,但是代理就是想成为目标的子类型,所以会冲突static  class Target{// 这个方法如果是final类型的也不能增强,因为既然是子夫级的关系,那肯定是通过方法的重写来获得的增强,既然是方法重写,那对于final类型肯定不再适用,因为final的方法是不能被重写不能被继承的public final void foo() {//加了final之后的输出结果为
//            target foo// 不会报错,但是不具备before、after的增强功能了System.out.println("target foo");}}//代理是子类型,目标是父类型//跟jdk的动态代理不一样,jdk中的代理跟目标是平级的兄弟关系,他们都实现了共同的接口public static void main(String[] args) {Target target = new Target();Target proxy = (Target)Enhancer.create(Target.class, (MethodInterceptor) (p, method, args1, methodProxy) -> {System.out.println("before...");
//            Object result = method.invoke(target, args);    //用方法反射调用目标// methodProxy 它可以避免反射调用
//            Object result = methodProxy.invoke(target,args);     //内部没有用反射,需要目标(spring)  但是看到的效果是一样的,都是输出////            before...//        target foo//        after...  但是内部确实没有用反射Object result = methodProxy.invokeSuper(p,args);   //内部没有用反射,需要代理    但是看到的效果是一样的,都是输出//        before...//        target foo//        after...System.out.println("after...");return result;});//第一个参数:代理的父类是什么  第二个参数,决定将来代理类中方法执行的行为//o指的是代理类自己,method指的是当前代理类中执行的方法,args指的是方法执行时的参数,methodProxy也可以看作是一个方法对象//输出结果为
//        before...
//        target foo
//        after...proxy.foo();}
}

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

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

相关文章

Vue3-readonly(深只读) 与 shallowReadonly(浅只读)

Vue3-readonly(深只读) 与 shallowReadonly(浅只读) readonly(深只读):具有响应式对象中所有的属性,其所有值都是只读且不可修改的。shallowReadonly(浅只读):具有响应式对象的第一层属性值是只读且不可修改的&#x…

使用requests库进行网络爬虫:IP请求错误的解决方法

目录 引言 一、了解requests库 二、遇到的问题 三、解决方法 1、随机化IP地址 2、减少请求频率 3、使用User Agent模拟浏览器行为 4、使用Cookies 四、注意事项 五、使用代理池 六、总结 引言 在利用Python的requests库进行网络爬虫操作时,我们有时会遇…

系列七、JVM的内存结构【堆(Heap)】

一、概述 一个JVM实例只存在一个堆内存,堆内存的大小是可以手动调节的。类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,保存所有引用类型的真实信息,以方便执行器执行,堆内存分为三个部分,即…

给openlab搭建web网站

1.作业的要求 2.访问www.openlab.com网站 2.1先准备好相关的包和关闭防火墙等操作 mount /dev/sr0 /mnt/ //先挂载 yum install httpd -y //下载htppd systemctl stop firewalld //关闭防火墙 setenforce 02.2然后开始配置文件和仓库 这一步比较关键,之前改了接口…

【OpenCV实现图像:OpenCV进行OCR字符分割】

文章目录 概要基本概念读入图像图像二值化小结 概要 在处理OCR(Optical Character Recognition,光学字符识别)时,利用传统的图像处理方法进行字符切分仍然是一种有效的途径。即便当前计算机视觉领域主导的是卷积神经网络&#xf…

JavaScript垃圾回收机制解析

JavaScript是一种动态语言,拥有自动内存管理。这意味着开发人员不需要手动分配和释放内存。在JavaScript中,垃圾回收器会自动处理不再需要使用的内存,以便重新利用。 1. 标记清除算法 JavaScript使用标记清除算法作为主要的垃圾回收机制。该…

DAO和增删改查通用方法-BasicDao

文章目录 一、BasicDao是什么?二、BasicDao分析三、BasicDao实现(1)BasicDao(2)ActorDao(3)TestDao 四、总结 一、BasicDao是什么? BasicDao:基础的数据对象,可以完成通用…

asp.net智能考试系统VS开发sqlserver数据库web结构c#编程计算机网页项目

一、源码特点 asp.net 智能考试系统 是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。 系统运行视频 https://www.bilibili.com/video/BV1gz4y1A7Qp/ 二、功能介绍 本系统使用Microsoft Visual Studio 201…

掌握键盘快捷键,在没有鼠标的情况下,也还是可以做到游刃有余,甚至可以用数字键来代替鼠标

键盘和鼠标是与计算机交互的重要外围设备。有些人可能会争辩说,你只需要这些设备中的一个,但事实上,只使用其中一个设备的电脑可能非常困难。但是,如果你的鼠标或笔记本电脑的触控板突然停止工作,而你无法修复它或无法使用备用鼠标,该怎么办? 在这种情况下,你可以使用…

树莓派4b编译FFmpeg支持硬件编解码

ffmpeg h264_omx解码器充分发挥树莓派gpu性能 准备 树莓派4b ,64位系统 修改树莓派的启动设置文件(/boot/config.txt)进行如下的调整: gpu_mem=256 framebuffer_depth=16安装依赖 常规依赖: sudo apt update sudo apt upgrade sudo apt -y install autoconf automake …

循环优先级仲裁~位屏蔽仲裁算法

参考了FPGA奇哥(下列视频中UP主)的讲解。 应该可以对多路读写DDR3进行操作,仅仲裁,不涉及DMA和Uibuf等。 2023年11月所写,暂未进行测试,日后补上。 第二天已完成测试,功能可行。 深入FPGA底层…

一生一芯18——Chisel模板与Chisel工程构建

Chisel模板链接如下: 链接: https://pan.baidu.com/s/1DNDKpz5VnTxPgoZBBOd-Ww?pwdrevg 提取码: revg Chisel转Verilog模板如下: 链接: https://pan.baidu.com/s/1T9JQL5BccxqI4bscfU-JyA?pwd7rw2 提取码: 7rw2 以下使用sbt作为构建工具 Chisel项目构…

DeepMind发布新模型Mirasol3B:更高效处理音频、视频数据

Google DeepMind日前悄然宣布了其人工智能研究的重大进展,推出了一款名为“Mirasol3B”的新型自回归模型,旨在提升对长视频输入的理解能力。该新模型展示了一种颠覆性的多模态学习方法,以更综合和高效的方式处理音频、视频和文本数据。 Googl…

MATLAB 模糊设计器 构建 模糊系统

系列文章目录 文章目录 系列文章目录前言一、创建 FIS 结构二、定义输入变量三、定义输出变量四、定义成员函数五、定义规则库六、设计分析七、存储和修改设计八、导出 FIS总结 前言 本例演示如何使用 Fuzzy Logic Designer 应用程序交互式创建 1 型 Mamdani 模糊推理系统&…

在线文档频繁故障不稳定,其实可以自己搭一个Etherpad在线文档

正文共:1116 字 20 图,预估阅读时间:2 分钟 最近某头部云厂商多次出现故障,导致在线文档使用受限,虽说影响不大,但我们有必要考虑一下是否有备用方案。 在自己搭建在线文档方面,我们之前测试过部…

Flutter打包iOS过程中pod访问github失败

问题描述 执行Flutter打包iOS命令出现如下错误: # flutter build ios ...Error output from CocoaPods: ↳Cloning into /var/folders/q8/sd0qtp6d69b30yt6gsh1jrg40000gq/T/d20231116-58127-8g2zje...fatal: unable to access https://github.com/ccgus/fmdb.git…

[Jenkins] 物理机 安装 Jenkins

这里介绍Linux CentOS系统直接Yum 安装 Jenkins,不同系统之间类似,操作命令差异,如:Ubuntu用apt; 0、安装 Jenkins Jenkins是一个基于Java语言开发的持续构建工具平台,主要用于持续、自动的构建/测试你的软…

uniapp基础学习笔记01

文章目录 本博客根据黑马教程学习uniapp一、技术架构二、创建项目2.1 Hbuilder创建2.2 插件安装2.3 微信开发者工具配置与运行2.3.1 简单修改基础页面 2.4 pages.json和tabBar2.4.1 pages.json与tabBar配置2.4.2 案例 3.1 通过命令行创建项目3.2 命令行运行项目3.2.1 命令行总结…

C#装箱与拆箱详解

装箱和拆箱是C#语言中非常重要的两个概念。在C#中,值类型(如int,double,struct等)和引用类型(如class,interface等)是两种完全不同的数据类型。而装箱和拆箱就是这两种类型之间转换的…

五、Linux目录结构

1.基本介绍 1.Linux的文件系统是采用级层式的树状目录结构,在此结构中的最上层是根目录"r/",然后在此目录下再创建其他的目录。 2.深刻理解linux树状文件目录是非常重要的 3.记住一句经典的话:在Linux世界里,一切皆文件…