在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 {

    @Override
    public 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.OnMethodEnter
    public static void onMethodEnter(@Advice.Origin Method method, @Advice.AllArguments Object[] arguments) {
        System.out.println("Enter " + method.getName() + " with arguments: " + Arrays.toString(arguments));
    }

    @Advice.OnMethodExit
    public 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 {
    @Autowired
    private 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();
    }

    @Bean
    public 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.mfbz.cn/a/598340.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大数据基础工程技术团队4篇论文入选ICLR,ICDE,WWW

近日&#xff0c;由阿里云计算平台大数据基础工程技术团队主导的四篇时间序列相关论文分别被国际顶会ICLR2024、ICDE2024和WWW2024接收。 论文成果是阿里云与华东师范大学、浙江大学、南京大学等高校共同研发&#xff0c;涉及时间序列与智能运维结合的多个应用场景。包括基于P…

【web前端2024】简单几步制作web3d《萌宠星球》智体节点模板!

使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引擎&#xff08;内嵌了three.js编辑器的定制版-支持以第一视角游览3D场馆&#xff…

音视频开发4 FFmpeg windows 环境搭建,QT 安装,动态库的搜索路径

FFmpeg 为了让所有平台的开发者都能够学习到音视频开发的通用技术&#xff0c;本教程主要讲解跨平台的音视频开发库FFmpeg。其实只要你掌握了FFmpeg&#xff0c;也可以很快上手其他音视频开发库&#xff0c;因为底层原理都是一样的&#xff0c;你最终操作的都是一样的数据&…

基于SSM的农产品销售管理系统

文章目录 项目介绍一、项目功能介绍二、部分页面展示三、部分源码四、底部获取全部源码&#xff08;9.9&#xffe5;带走&#xff09; 项目介绍 农产品销售管理系统 一、项目功能介绍 一、介绍 系统分为两个角色 用户功能&#xff1a;登陆&#xff0c;注册&#xff0c;商品分…

工业光源环形系列一高亮条形光源特点

产品特点 ◆可以根据检测需求随意调整照射角度&#xff1b; ◆可以根据检测需求选择光源颜色&#xff1b; ◆多个条形光源可以自由组合&#xff1b; ◆使用大功率贴片灯珠&#xff0c;亮度高&#xff1b; ◆灯珠上面增加透镜&#xff0c;照射距离更远

一站式PDF解决方案:如何部署自己的PDF全能工具(Docker部署和群晖部署教程)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 开始部署 📒📝 Docker部署📝 群晖部署📝 本地安装⚓️ 相关链接 ⚓️📖 介绍 📖 在数字化办公的今天,PDF文件几乎成了我们日常工作中不可或缺的一部分。但你是否曾因为PDF文件的编辑、转换、合并等问题而头疼?如果…

一文快速掌握高性能内存队列Disruptor

写在文章开头 Disruptor是英国外汇公司LMAX开源的一款高性能内存消息队列&#xff0c;理想情况下单线程可支撑600w的订单。所以本文会从使用以及设计的角度来探讨一下这款神级java消息队列。 Hi&#xff0c;我是 sharkChili &#xff0c;是个不断在硬核技术上作死的 java code…

中学数学重大错误:射线A沿其正向平移非0距离就变为其真子集了

黄小宁 射线A沿其射出的方向平移非0距离变为B≌A&#xff0c;中学数学一直认定B是A的一部分&#xff0c;其实这是将两异射线&#xff08;函数&#xff09;误为同一射线&#xff08;函数&#xff09;的肉眼直观错觉。设“点集A&#xff5b;点p&#xff5d;”表示A的元素是点p&a…

MongoDB(四):条件操作符

条件操作 1、概述2、比较操作2.1、大于操作符-$gt2.2、大于等于操作符-$gte2.3、小于——$lt2.4、小于等于——$lte2.5、范围查询 3、总结 大家好&#xff0c;我是欧阳方超&#xff0c;可以扫描下方二维码关注我的公众号“欧阳方超”&#xff0c;后续内容将在公众号首发。 1、…

python实现图书馆借阅管理系统-文件存储

《面向对象》案例引入 通过本章的学习,请用面向对象思想实现《图书馆借阅管理系统》的登录注册页面和用户信息维护页面和图书借阅页面。 【功能要求】: 1、用面向对象思想改写上一章的《函数模块》案例引入。 2、增加图书借阅页面。 ①学生登录后,可以进入图书借阅页面,实现…

ROS摄像头标定

目录 一、内容概要二、 配置ubuntu摄像头环境2.1 硬件准备2.2 软件准备 三、 完成摄像头标定四、 标定结果运用五、 实验心得参考链接 一、内容概要 配置ubuntu摄像头环境进行摄像头标定 二、 配置ubuntu摄像头环境 2.1 硬件准备 1.电脑自带摄像头 或 2.USB外设摄像头 在原…

ASV1000视频监控平台:接入支持JT808标准的设备

目录 一、JT/T 808标准简介 &#xff08;一&#xff09;概述 &#xff08;二&#xff09;标准内容简介 1、消息分类 2、位置信息 3、报警信息 4、车辆控制 5、数据转发 二、在ASV1000上通过JT808添加设备 &#xff08;一&#xff09;登录视频监控平台管理端 &#x…

Hass哈斯数控数据采集网络IP配置设置

机床数据采集&#xff08;MDC&#xff09;允许你使用Q和E命令通过网络接口或选项无线网络从控制系统提取数据。设置143支持该功能&#xff0c;并且指定控制器使用这个数据端口。MDC是一个需要一台附加计算机发送请求&#xff0c;解释说明和存储机床数据的软件功能。这个远程计算…

使用pytorch构建GAN网络并实现FID评估

上一篇文章介绍了GAN的详细理论&#xff0c;只要掌握了GAN&#xff0c;对于后面各种GAN的变形都变得很简单&#xff0c;基础打好了&#xff0c;盖大楼自然就容易了。既然有了理论&#xff0c;实践也是必不可少的&#xff0c;这篇文章将使用mnist数据集来实现简单的GAN网络&…

如何从Mac上的清空垃圾箱中恢复已删除的文件?

Mac用户几乎每天都会删除文件。当您将文档删除到 Mac 垃圾箱时&#xff0c;该文件将被剪切到 Mac 垃圾箱中&#xff0c;并且可以轻松放回原处。但是&#xff0c;在某些情况下&#xff0c;您错误地删除了文档和文件&#xff0c;并在您意识到自己犯了一个大错误之前清空了垃圾箱。…

Advanced RAG 06:生成结果的相关性低? 快用 Query Rewriting 优化技术

编者按&#xff1a;在现实生活中&#xff0c;普通用户很难编写合适的提示词&#xff08;prompt&#xff09;来指示 LLM 完成期望任务。用户提出的 queries 往往存在词汇不准确、缺乏语义信息等问题&#xff0c;导致 LLM 难以理解并生成相关的模型响应。因此&#xff0c;如何优化…

刷代码随想录有感(58):二叉树的最近公共祖先

题干&#xff1a; 代码&#xff1a; class Solution { public:TreeNode* traversal(TreeNode* root, TreeNode* p, TreeNode* q){if(root NULL)return NULL;if(root p || root q)return root;TreeNode* left traversal(root->left, p, q);TreeNode* right traversal(r…

JuiceFS v1.2-beta1,Gateway 升级,多用户场景权限管理更灵活

JuiceFS v1.2-beta1 今天正式发布。在这个版本中&#xff0c;除了进行了大量使用体验优化和 bug 修复外&#xff0c;新增三个特性&#xff1a; Gateway 功能扩展&#xff1a;新增了“身份和访问管理&#xff08;Identity and Access Management&#xff0c;IAM&#xff09;” 与…

泛型编程四:栈、堆,内存管理

文章目录 前言一、栈、堆栈&#xff08;Stack&#xff09;堆&#xff08;Heap&#xff09; 二、static生命期三、heap生命期四、new、delete的作用机制五、动态分配的内存&#xff08;in VC&#xff09;如图&#xff0c;第一列为调试模式下的复数的内存分配&#xff0c;复数有两…

电子合同:纸质合同的未来替代者?

随着科技的迅猛发展&#xff0c;电子合同作为一种新兴的合同形式&#xff0c;逐渐在各行各业中崭露头角。那么&#xff0c;电子合同是否会替代纸质合同&#xff0c;成为未来合同形式的主流呢&#xff1f;本文将就此话题展开探讨。 首先&#xff0c;我们来看电子合同的优势。电…
最新文章