在spring中使用bytebuddy 对bean做Aop拦截

背景

拦截spring 中的某个bean拦截其方法的调用。在其前后做一些类似于aop的操作

拦截bean

  • MyBeanDefinitionRegistryPostProcessor
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.asm.Advice;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.returns;/*** @author wxl*/
@Slf4j
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {boolean userService = registry.containsBeanDefinition("userService");if (userService) {registry.removeBeanDefinition("userService");Class<? extends UserService> method02 = new ByteBuddy().subclass(UserService.class).method(named("method02").and(returns(String.class))).intercept(Advice.to(LoggerAdvisor.class)).make().load(getClass().getClassLoader()).getLoaded();BeanDefinition beanDefinitions = BeanDefinitionBuilder.rootBeanDefinition(method02).getBeanDefinition();beanDefinitions.setAutowireCandidate(true);registry.registerBeanDefinition("userService", beanDefinitions);}}}
  • LoggerAdvisor
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.asm.Advice;import java.lang.reflect.Method;
import java.util.Arrays;/*** @author wxl*/
@Slf4j
public class LoggerAdvisor {@Advice.OnMethodEnterpublic static void onMethodEnter(@Advice.Origin Method method, @Advice.AllArguments Object[] arguments) {System.out.println("Enter " + method.getName() + " with arguments: " + Arrays.toString(arguments));}@Advice.OnMethodExitpublic static void onMethodExit(@Advice.Origin Method method, @Advice.AllArguments Object[] arguments, @Advice.Return Object ret) {System.out.println("Exit " + method.getName() + " with arguments: " + Arrays.toString(arguments) + " return: " + ret);}
}
  • BeanB

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** @author wxl*/
@Component
public class BeanB {@Autowiredprivate UserService userService;public void test() {System.out.println("beanB");userService.method02("ss");}
}
  • 测试
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;/*** @author wxl*/
@Slf4j
@SpringBootApplication
public class SpringBytecodeDemoApplication {public static void main(String[] args) throws Exception {
//        ClassPool pool = ClassPool.getDefault();
//        CtClass cc = pool.get("cc.sofast.demo.springbytecodedemo.UserService");
//        cc.defrost();
//        CtMethod m = cc.getDeclaredMethod("say");
//        m.insertBefore("{ System.out.println(\"Hello.say():\"); }");
//        m.insertAfter("{ System.out.println(\"result: \"+$_); }");
//        cc.writeFile(".");
//        cc.toClass();
//        ByteBuddyAgent.install();
//
//        new ByteBuddy()
//                .redefine(UserService.class)
//                .method(named("method02").and(returns(String.class)))
//                .intercept(to(new OvUserService()))
//                .make()
//                .load(UserService.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());ConfigurableApplicationContext context = SpringApplication.run(SpringBytecodeDemoApplication.class, args);BeanB bean = context.getBean(BeanB.class);bean.test();}@Beanpublic MyBeanDefinitionRegistryPostProcessor myBeanDefinitionRegistryPostProcessor() {return new MyBeanDefinitionRegistryPostProcessor();}}
  • build.gradle
    implementation 'org.javassist:javassist:3.30.2-GA'implementation 'net.bytebuddy:byte-buddy:1.14.14'implementation 'net.bytebuddy:byte-buddy-agent:1.14.14'
  • 总结
    • 可以拦截其中的任意方法。在其前后做一些事情

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

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

相关文章

Linux下网络编程-简易Epll服务器和客户端

Linux下网络编程-简易Epll服务器和客户端 简易Epll服务器: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <sys/epoll.h>#define B…

NIO BIO AIO详解

BIO: 同步阻塞I/O&#xff0c;是JDK1.4之前的传统IO模型。 线程发起IO请求后&#xff0c;一直阻塞&#xff0c;直到缓冲区数据就绪后&#xff0c;再进入下一步操作。 NIO:同步非阻塞IO&#xff0c;当线程发起IO请求后&#xff0c;不需要阻塞&#xff0c;会立即返回。用户线程不…

对视频实现人脸识别

惯例先上结果&#xff1a; 在c opencv Chapter8 - Face Detection中介绍了人脸图片的标记&#xff0c;而视频其实是每一帧图片所组成&#xff0c;因此也能实现对视频的人脸识别&#xff0c;由于模型的劣势&#xff0c;实现的效果一般。 重点介绍写出视频函数&#xff1a;out.o…

linux学习笔记——硬盘原理以及linux中的sector与block

在计算机硬盘中&#xff0c;最小的存储单位叫做扇区sector&#xff0c;0.5kb&#xff0c;多个连续扇区组合在一起形成了块block&#xff0c;最小的块包含8个扇区&#xff0c;4kb 我们可以在linux中印证 创建一个新的文件2.txt&#xff0c;查看文件大小为0k 在文件中添加字符后…

Gradle基础学习(七) 认识插件

Gradle构建在一个插件系统上&#xff0c;本身主要由基础设施组成&#xff0c;比如有一个先进的依赖解析引擎&#xff0c;而其他功能则来自插件。 插件是提供额外功能给Gradle构建系统的软件组件。 插件可以被应用到Gradle构建脚本中&#xff0c;以添加新的任务、配置或其他与构…

第八篇:深入探索操作系统架构:从基础到前沿

深入探索操作系统架构&#xff1a;从基础到前沿 1 引言 在当今这个高速发展的数字时代&#xff0c;操作系统无疑是计算机科学领域的基石之一。它不仅是计算机硬件与最终用户之间的桥梁&#xff0c;更是实现高效计算和资源管理的关键。操作系统的架构&#xff0c;即其内部结构和…

51单片机入门:蜂鸣器

蜂鸣器介绍 蜂鸣器是一种将电信号转换为声音信号的器件&#xff0c;常用来产生设备的按键音、报警音等提示信号。 蜂鸣器的种类 1、从结构上&#xff1a;压电式蜂鸣器和电磁式蜂鸣器。 压电式蜂鸣器&#xff1a;通过压电陶瓷的压电效应原理工作的。当加有交变电压时&#xf…

企业微信主体能不能修改?

企业微信变更主体有什么作用&#xff1f;当我们的企业因为各种原因需要注销或已经注销&#xff0c;或者运营变更等情况&#xff0c;企业微信无法继续使用原主体继续使用时&#xff0c;可以申请企业主体变更&#xff0c;变更为新的主体。企业微信变更主体的条件有哪些&#xff1…

代码随想录算法训练营第36期DAY20

DAY20 110平衡二叉树 自己写的迭代法和递归都有问题&#xff0c;应该从&#xff1a;传入节点的树是否为平衡二叉树来考虑&#xff08;大部分时候是subtree。 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * Tre…

C 深入指针(2)

目录 1 野指针 1.1 成因 1.2 如何规避野指针 2 assert 断言 2.1 用法 2.2 assert 的优点 2.1 assert 的缺点 3 小注解 3.1 Debug 和 Release 1 野指针 【概念】&#xff1a; 野指针就是指针指向的位置是不可知的&#xff08;随机的、不正确的、没有明确限制的&#…

CSS Web服务器、2D、动画和3D转换

Web服务器 我们自己写的网站只能自己访问浏览&#xff0c;但是如果想让其他人也浏览&#xff0c;可以将它放到服务器上。 什么是Web服务器 服务器(我们也会称之为主机)是提供计算服务的设备&#xff0c;它也是一台计算机。在网络环境下&#xff0c;根据服务器提供的服务类型不…

初识C语言——第十三天

关键字2&#xff1a; static 修饰局部变量&#xff0c;改变了局部变量的生命周期&#xff08;本质上是改变了变量的存储类型&#xff09; static修饰全局变量&#xff0c;使得这个全局变量只能在自己所在的源文件&#xff08;.c)内部可以使用&#xff0c;其他源文件不能使用 …

【Kafka每日一问】Kafka分区分配策略有哪些?

Kafka分区分配策略有哪些 Range分配策略&#xff08;Range&#xff09;&#xff1a; 这是默认的分配策略。在这种策略下&#xff0c;每个消费者负责订阅主题的连续范围内的分区。例如&#xff0c;如果有两个消费者和一个主题有12个分区&#xff0c;那么第一个消费者将负责分区0…

嵌入式交叉编译:x264

下载 Index of /x264/snapshots/ 解压编译 BUILD_DIR${HOME}/build_libsCROSS_NAMEaarch64-mix210-linuxmake clean./configure \--prefix${BUILD_DIR} \--cross-prefix${CROSS_NAME}- \--hostaarch64-linux-gnu \--enable-sharedmake -j16make install 检查 file ${BUILD…

Partisia Blockchain 生态zk跨链DEX上线,加密资产将无缝转移

在 5 月 1 日&#xff0c;由 Partisia Blockchain 与 zkCross 创建合作推出的 Partisia zkCrossDEX 在 Partisia Blockchain 生态正式上线。Partisia zkCrossDEX 是 Partisia Blockchain 上重要的互操作枢纽&#xff0c;其融合了 zkCross 的 zk 技术跨链互操作方案&#xff0c;…

Linux基础知识(升级版)

Linux基础知识&#xff08;常用命令史上最全版&#xff09; 前言 至于为什么重新写Linux笔记&#xff0c;之前作为Java攻城狮&#xff0c;学的太片面&#xff0c;重新整理以前的笔记&#xff0c;打造更好的&#xff0c;学习更高深的技术&#xff0c;挣更多的money常见目录 目…

《华为鸿蒙:从备胎到主角的崛起之路》

华为鸿蒙操作系统的发展历程可以追溯到 2012 年&#xff0c;当时华为开始规划自有操作系统鸿蒙 OS。然而&#xff0c;直到 2019 年 5 月&#xff0c;鸿蒙才正式进入开发阶段。 2019 年 8 月 9 日&#xff0c;华为正式发布了鸿蒙操作系统。 鸿蒙系统的首个版本是于 2019 年推出…

linux上Redis安装使用

环境centOS8 redis是缓存数据库&#xff0c;主要是用于在内存中存储数据&#xff0c;内存的读写很快&#xff0c;加快系统读写数据库的速度 一、Linux 安装 Redis 1. 下载Redis 官网下载Downloads - Redis 历史版本Index of /releases/ 本文中安装的版本为&#xff1a;h…

小红书图片文案编辑生成图文工具

在小红书上&#xff0c;种草图文的变现通常涉及以下几个步骤&#xff1a; 1. **建立影响力**&#xff1a;首先&#xff0c;你需要通过持续发布高质量的内容&#xff0c;积累粉丝和影响力。你的内容应该围绕特定的领域或主题&#xff0c;比如时尚、美妆、美食或旅行&#xff0c…

KUKA机器人KR3 R540维护保养——涂润滑脂

KUKA机器人在保养时少不了润滑脂&#xff0c;不同型号的机器人需要的润滑脂类型也不一样&#xff0c;保养时注意选用合适的润滑脂。本篇文章以KUKA机器人KR3 R540为例&#xff0c;在轴盖板 A2、A3、A5 的内侧涂上润滑脂。 一、涂润滑脂的作用 拆开机器人一个轴的盖板&am…