AOP底层实现原理

一、JDK

  • 核心思想:
    原始类和代理类实现相同的接口

使用JDK自带api创建动态代理

public class JDKTest{public static void main(String[] args){// 获取原始对象UserService userService = new UserServiceImpl();ClassLoader classLoader = JDKTest.class.getClassLoader();Class<?>[] interfaces = userService.getClass().getInterfaces();InvocationHandler invocationHandler = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("====执行原始方法之前====");// 运行原始方法Object ret = method.invoke(userService, args);System.out.println("====执行原始方法之后====");return ret;}};UserService userServiceProxy = (UserService)Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);userServiceProxy.register(new User());userServiceProxy.login("zhl", "123");}
}
  1. 类加载器的作用(ClassLoader)
    类加载器把对应类的字节码文件(.class)加载到JVM,创建这个类的Class对象,进而创建这个类的对象。
    动态字节码技术没有创建代理类的源文件和字节码文件,但是需要创建动态代理类的对象,所以需要借用一个类加载器。
  2. interfaces
    原始类实现的接口
  3. InvocationHandler
    为原始类中的原始方法添加额外功能

二、Cglib

  • 核心思想:
    代理类继承原始类

使用Cglib创建动态代理,创建过程大致和JDK方式类似

public class CglibTest {public static void main(String[] args) {// 原始对象UserService userService = new UserService();Enhancer enhancer = new Enhancer();// 为动态代理类设置类加载器enhancer.setClassLoader(CglibTest.class.getClassLoader());// 设置原始类为父类,添加额外功能enhancer.setSuperclass(userService.getClass());MethodInterceptor interceptor = new MethodInterceptor() {@Overridepublic Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {System.out.println("----------cglib before--------");Object ret = method.invoke(userService, args);System.out.println("----------cglib after--------");return ret;}};// callback <===> invocationHandlerenhancer.setCallback(interceptor);// 创建代理对象UserService serviceProxy = (UserService) enhancer.create();serviceProxy.login("zzz", "222");serviceProxy.register(new User());}
}

三、BeanPostProcessor

Spring工厂如何加工原始对象?
思路分析:
在这里插入图片描述
简单代码实现:

public class ProxyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {InvocationHandler invocation = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("--------核心功能之前---------");Object ret = method.invoke(bean, args);System.out.println("--------核心功能之后---------");return ret;}};return Proxy.newProxyInstance(ProxyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(),invocation);}
}
<bean id="userService" class="com.zhl.factory.UserServiceImpl"/>
<!--对当前配置文件中的所有bean进行加工-->
<bean id="proxyBeanPostProcessor" class="com.zhl.factory.ProxyBeanPostProcessor"/>

这里的实现比较粗糙,没有引入切入点,对整个Spring工厂中的bean都进行了加工。

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

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

相关文章

外包干了6天,技术明显进步

先说一下自己的情况&#xff0c;本科生&#xff0c;2019年我通过校招踏入了南京一家软件公司&#xff0c;开始了我的职业生涯。那时的我&#xff0c;满怀热血和憧憬&#xff0c;期待着在这个行业中闯出一片天地。然而&#xff0c;随着时间的推移&#xff0c;我发现自己逐渐陷入…

数据结构——图

链接: 来源&#xff1a;link 1、基础知识 2、图的存储结构 1、邻接矩阵 注意&#xff1a; 邻接矩阵表示法的空间复杂度为O(n^2)&#xff0c; 其中n为图的顶点数∣V∣。用邻接矩阵法存储图&#xff0c;很容易确定图中任意两个顶点之间是否有边相连。但是&#xff0c;要确定图…

记一次DNS故障导致用户无法充值的问题(下)

上一篇说到DNS故障导致无法充值&#xff0c;后来我们通过拨测发现业务域名的解析目标地址被解析到了【127.0.0.1】IP。 1、联系阿里云厂商&#xff0c;通过沟通&#xff0c;阿里云反馈我们的域名被XX省通管单位封禁了&#xff0c;导致解析到了不正确的地址。 2、为了解决用户问…

使用Simulink Test进行单元测试

本文摘要&#xff1a;主要介绍如何利用Simulink Test工具箱&#xff0c;对模型进行单元测试。内容包括&#xff0c;如何创建Test Harness模型&#xff0c;如何自动生成excel格式的测试用例模板来创建测试用例&#xff0c;如何手动填写excel格式的测试用例模板来手动创建测试用例…

面向新手在无人机竞速场景下的飞行辅助系统——浙大 FAST-Lab 高飞团队 ICRA 论文三项 Best Paper 入围

恭喜浙江大学 FAST-Lab 钟宇航同学的论文 A Trajectory-based Flight Assistive System for Novice Pilots in Drone Racing Scenario 顺利发表 ICRA 2024&#xff0c;并同时入选三项 Finalist&#xff1a; the IEEE ICRA Best Conference Paper Awardthe IEEE ICRA Best Pape…

git与gitlab

目录 gitlab 下载与安装 重置管理员密码 邮箱配置 gitlab命令 git远程gitlab相关命令 gitlab的使用 设置中文 修改默认分支 创建群组并授权 新建项目/新建库 设置当前用户的sshkey Deploy Keys 计划管理 权限管理 gitlab的备份与恢复 git git 分布式版本控制 …

mysql安装及基础设置

关系型数据库 MySQL是一种关系型数据库管理系统&#xff0c;采用了关系模型来组织数据的数据库&#xff0c;关系数据库将数据保存在不同的表中&#xff0c;用户通过查询 sql 来检索数据库中的数据。 yum 方式安装 mysql # yum -y install mysql-server # systemctl start my…

Linux -- 日志

一 日志的重要性 在之前的编程经历中&#xff0c;如果我们的程序运行出现了问题&#xff0c;都是通过 标准输出 或 标准错误 将 错误信息 直接输出到屏幕上&#xff0c;以此来排除程序中的错误。 这在我们以往所写的程序中使用没啥问题&#xff0c;但如果出错的是一个不断在运行…

快速上手prometheaus grafana 监控

介绍 prometheaus 一个定时输出指标数据的巡检组件&#xff1f; grafana 一个读取指标&#xff0c;可视化的提供了好看界面的组件&#xff1f; 教程 如何和springboot项目集成 【IT老齐153】超级实用&#xff01;十分钟掌握Prometheus与Grafana监控SpringBoot应用_哔哩哔哩_…

计算机网络 备查

OSI 七层模型 七层模型协议各层实现的功能 简要 详细 TCP/IP协议 组成 1.传输层协议 TCP 2.网络层协议 IP 协议数据单元&#xff08;PDU&#xff09;和 封装 数据收发过程 数据发送过程 1. 2.终端用户生成数据 3.数据被分段&#xff0c;并加上TCP头 4.网络层添加IP地址信息…

luceda ipkiss教程 68:通过代码模板提高线路设计效率

在用ipkiss设计器件或者线路时&#xff0c;经常需要输入: from ipkiss3 import all as i3那么有什么办法可以快速输入这段代码呢&#xff1f;这里就可以利用Pycharm的 live template功能&#xff0c;只需要将文件&#xff1a;ipkiss.xml &#xff08;luceda ipkiss教程 68&…

Docker快速搭建NAS服务——FileBrowser

Docker快速搭建NAS服务——FileBrowser 文章目录 前言FileBrowser的搭建docker-compose文件编写运行及访问 总结 前言 本文主要讲解如何使用docker在本地快速搭建NAS服务&#xff0c;这里主要写如下两种&#xff1a; FileBrowser1&#xff1a;是一个开源的Web文件管理器&…

QT功能 实现静态内容国际化实验

文章目录 第一步&#xff1a;新建一个QT工程第二步&#xff1a;添加控件第三步&#xff1a;在pro文件中添加内容第四步&#xff1a;更新文件第五步&#xff1a;打开QT的Linguist第六步&#xff1a;添加翻译内容第七步&#xff1a;回到QT Creator中添加文件第八步&#xff1a;给…

软考中级-软件设计师(九)数据库技术基础 考点最精简

一、基本概念 1.1数据库与数据库系统 数据&#xff1a;是数据库中存储的基本对象&#xff0c;是描述事物的符号记录 数据库&#xff08;DataBase&#xff0c;DB&#xff09;&#xff1a;是长期存储在计算机内、有组织、可共享的大量数据集合 数据库系统&#xff08;DataBas…

微服务总览

微服务保护 微服务总览 微服务总览 接入层&#xff1a;反向代理功能&#xff0c;可以将用户域名访问的地址以负载均衡的方式代理到网关地址&#xff0c;并且并发能力非常高&#xff0c;并且会采用主备nginx的方式防止nginx寄了&#xff0c;备份nginx监控主nginx状态&#xff0c…

YOLOV5更换转置卷积,助力涨点!

由于转置卷积是nn库自带的,所以我们直接找到models文件夹中的yolo.py文件中的 parse_model函数,再在如下图的地方添加转置卷积模块 # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license """ YOLO-specific modules.Usage:$ python models/yolo.py --cfg yolov5s.…

Spring AOP(2)

目录 Spring AOP详解 PointCut 切面优先级Order 切点表达式 execution表达式 切点表达式示例 annotation 自定义注解MyAspect 切面类 添加自定义注解 Spring AOP详解 PointCut 上面代码存在一个问题, 就是对于excution(* com.example.demo.controller.*.*(..))的大量重…

FPGA -手写异步FIFO

一&#xff0c;FIFO原理 FIFO&#xff08;First In First Out&#xff09;是一种先进先出的数据缓存器&#xff0c;没有外部读写地址线&#xff0c;使用起来非常简单&#xff0c;只能顺序写入数据&#xff0c;顺序的读出数据&#xff0c;其数据地址由内部读写指针自动加1完成&a…

案例研究|硬之城借助DataEase以数据驱动供应链精细化管理

深圳硬之城信息技术有限公司&#xff08;以下简称为“硬之城”&#xff09;成立于2015年&#xff0c;专注电子元件供应链领域&#xff0c;定位于电子产业供应链与智造平台。硬之城通过名为“Allchips”的集成式服务平台&#xff0c;为客户提供一站式的电子元件采购和供应链管理…

ROS八股总结

1. 概述 ROS系统是为了提高机器人研发中的软件复用率&#xff0c;每个模块可以被单独设计与编译&#xff0c;运行时以松耦合的方式结合在一起。提供硬件抽象、底层驱动、消息传递、程序管理、应用原型等功能和机制。且集成了大量工具、库、协议 2.特点 点对点 节点单元分布式…