Java开发-面试题-0035-Spring代理方式有哪些

news2024/9/20 19:37:05

Java开发-面试题-0035-Spring代理方式有哪些

更多内容欢迎关注我(持续更新中,欢迎Star✨)

Github:CodeZeng1998/Java-Developer-Work-Note

(技术)微信公众号:CodeZeng1998

(生活)微信公众号:好锅

其他平台:CodeZeng1998好锅


Spring 中的代理方式主要有两种:JDK 动态代理CGLIB 代理。两者在 Spring AOP 和 事务管理 中都被广泛使用。下面是对这两种代理方式的详细说明:


1. JDK 动态代理

概念:

JDK 动态代理是基于 Java 的 java.lang.reflect.Proxy 类和 InvocationHandler 接口来实现的。它只针对接口进行代理,因此代理类必须实现某个接口。


工作原理:
  • JDK 动态代理通过在运行时生成一个代理类,该代理类实现了目标对象所实现的接口。
  • 当代理对象调用接口中的方法时,代理类会拦截该方法调用,并将其交由 InvocationHandler 处理。
  • InvocationHandler 中,开发者可以定义代理逻辑,例如方法执行前后增强、权限检查、事务管理等。

特点:
  • 只能代理实现了接口的类。
  • 代理是基于接口调用的,因此目标对象必须实现一个或多个接口。
  • 代理类是在运行时动态生成的,无需在编译时定义。

使用场景:

Spring 会优先选择使用 JDK 动态代理,前提是目标类有实现接口,比如通过 AOP 进行事务控制时,常见的 service 层使用的是接口。


示例代码:
public interface Service {
    void perform();
}

public class ServiceImpl implements Service {
    @Override
    public void perform() {
        System.out.println("Performing service operation...");
    }
}

public class ServiceInvocationHandler implements InvocationHandler {
    private final Object target;
    
    public ServiceInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method execution...");
        Object result = method.invoke(target, args);
        System.out.println("After method execution...");
        return result;
    }
}

public class Main {
    public static void main(String[] args) {
        Service service = new ServiceImpl();
        Service proxy = (Service) Proxy.newProxyInstance(
                service.getClass().getClassLoader(),
                service.getClass().getInterfaces(),
                new ServiceInvocationHandler(service));
        
        proxy.perform();
    }
}

2. CGLIB 代理

概念:

CGLIB(Code Generation Library)代理是基于底层字节码生成的代理技术。它通过扩展(继承)目标类并在运行时生成代理类来实现方法拦截。CGLIB 代理不需要目标对象实现接口,因此它可以代理任何类。


工作原理:
  • CGLIB 使用 ASM 字节码操作框架在运行时生成目标类的子类,并重写目标类中的方法来实现代理。
  • 当代理类调用被代理类的方法时,代理类通过方法拦截器(MethodInterceptor)来增强方法逻辑。

特点:
  • 能够代理没有实现接口的类,即可以代理普通的类。
  • 代理是基于子类的,代理类实际上是目标类的子类,因此不能代理 final 类以及 final 方法。
  • 性能通常比 JDK 动态代理稍高,但由于生成类字节码的开销,代理类的生成较为复杂。

使用场景:

当目标类没有实现接口时,Spring 会选择使用 CGLIB 代理,例如在纯 POJO 类或者只实现抽象类的情况下,事务管理和 AOP 增强都需要使用 CGLIB 来代理。


示例代码:
public class Service {
    public void perform() {
        System.out.println("Performing service operation...");
    }
}

public class ServiceMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Before method execution...");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("After method execution...");
        return result;
    }
}

public class Main {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Service.class);
        enhancer.setCallback(new ServiceMethodInterceptor());
        
        Service proxy = (Service) enhancer.create();
        proxy.perform();
    }
}

3. Spring 中的代理选择机制

Spring 默认优先使用 JDK 动态代理,但如果目标对象没有实现任何接口,它会自动切换到 CGLIB 代理。具体的选择机制是:

  • 如果目标对象实现了接口,Spring 会使用 JDK 动态代理。
  • 如果目标对象没有实现接口,Spring 会使用 CGLIB 代理。

可以通过 @EnableAspectJAutoProxy(proxyTargetClass = true) 强制 Spring 使用 CGLIB 代理,即使目标类实现了接口。


4. 代理方式的选择

  • JDK 动态代理:适合目标对象实现了接口的情况。优点是代理类轻量、生成简单,缺点是只能代理接口。
  • CGLIB 代理:适合目标对象没有实现接口或希望通过继承的方式进行代理的情况。优点是代理范围广,能够代理任何类,缺点是不能代理 final 类或 final 方法,生成代理类较复杂。

总结来看,Spring 的代理机制在灵活性和性能上都非常适合于不同的业务场景,而 JDK 动态代理和 CGLIB 各有其适用场景,开发者可以根据需要选择合适的代理方式。


以上就是本文相关的所有内容了,如果发现有误欢迎评论指正,更多内容欢迎各位关注。

在这里插入图片描述

上图是由 Pic 生成的

关键词:Iron Man


更多内容欢迎关注我(持续更新中,欢迎Star✨)

Github:CodeZeng1998/Java-Developer-Work-Note

(技术)微信公众号:CodeZeng1998

(生活)微信公众号:好锅

其他平台:CodeZeng1998好锅

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

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

相关文章

品牌力是什么?如何评估企业品牌影响力?

品牌影响力,其实就是指品牌在消费者心智中所占据的位置,以及它对消费者购买决策和行为的影响力。如果一个企业的品牌影响力越强,它在消费者心中的印象就越深刻,能够更有效地驱动消费者的购买行为,形成品牌忠诚度&#…

SpringCloud (1) 服务拆解

1 服务拆解和治理 1.1 服务拆解 微服务的核心就是服务拆分,将传统的大项目拆分为多个微型服务(服务或微服务),实现服务之间"高内聚(微服务职责单一),低耦合(微服务功能相对独立)"的目的 (1) 水平(横向)拆分:先搭出拆分框架,比如【公共服务】(比如:common服务,client…

数字工厂管理系统与MES系统在实际应用中有哪些区别

随着制造业的数字化转型步伐加快,数字工厂管理系统与制造执行MES系统作为两大关键工具,在实际应用中展现出了明显的差异。本文将从实际应用的角度,详细探讨这两种系统之间的主要区别。 数字工厂管理系统的实际应用 数字工厂管理系统侧重于对…

Java基础(中)

面向对象基础 面向对象和面向过程的区别 面向过程编程(Procedural-Oriented Programming,POP)和面向对象编程(Object-Oriented Programming,OOP)是两种常见的编程范式,两者的主要区别在于解决…

monaco editor 在react中的使用

1. 首先先导入monaco editor npm install monaco-editor// npm install monaco-editor --force // 版本冲突? 强行安装 2. 在react中使用 期望效果如下 3. 我遇到的问题 : 输入json数据后 未格式化 , json数据仍然一行展示 我遇到的问题 : 直接输入json数据会白屏报错…

OSSEC搭建与环境配置Ubuntu

尝试使用Ubuntu配置了OSSEC,碰见很多问题并解决了,发表博客让后来者不要踩那么多坑 环境 : server :Ubuntu22.04 64位 内存4GB 处理器4 硬盘60G agent: 1.Windows11 64位 2.Ubuntu22.04 64位 服务端配置 一、配置安装依赖项&…

解决Python模块导入报错的问题

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 模块导入 📒📝 实际案例分享📝 解决方案📝 导入包的技巧和常见问题1. 导入包的技巧2. 常见问题及注意事项⚓️ 相关链接 ⚓️📖 介绍 📖 今天写Python代码的时候,遇到了一个模块导入报错的情况,这个问题不仅困扰了…

CDGA|怎样的数据治理状态才能被视为是良性发展的呢?

在当今这个数据驱动的时代,数据已成为企业最宝贵的资产之一,其质量、安全性和有效利用程度直接关系到企业的竞争力与可持续发展。因此,构建并维持一个良性的数据治理状态,对于企业而言至关重要。那么,怎样的数据治理状…

Linux中使用Docker容器构建Tomcat容器完整教程

🏡作者主页:点击! 🐧Linux基础知识(初学):点击! 🐧Linux高级管理防护和群集专栏:点击! 🔐Linux中firewalld防火墙:点击! ⏰️创作…

高效分数查询系统助力管理班级

老师们的工作现在可太忙啦!每天要做的事儿那叫一个繁杂。就说备课吧,得翻好多书,参考不同的教材,还得考虑每个学生的学习情况,想办法让课讲得有意思又能让学生学到东西。 从上课一开始怎么吸引学生,到中间每…

智慧交通,智能消防系统助力高铁站安全

智慧交通是一项基于现代技术的创新领域,正不断为我们生活带来便利。在智慧交通领域中,高铁站是一个非常重要的环节。高铁站作为人流密集的区域,安全问题一直备受关注。为了提升高铁站的安全性和效率,智慧消防设备监测与集中监控系…

20240919 - 【PYTHON】辞职信

import tkinter as tk # 导入 tkinter 模块,并简写为 tk from tkinter import messagebox # 从 tkinter 导入 messagebox 子模块,用于显示消息框 from random import random # 从 random 模块导入 random 函数,用于生成随机数# 创建窗口对…

ai写作软件排行榜前十名,5个软件帮助你快速使用ai写作

ai写作软件排行榜前十名,5个软件帮助你快速使用ai写作 AI写作软件已经成为许多人工作和创作中的重要工具,尤其是在快速生成内容、提高写作效率以及优化文本方面。以下是五款优秀的AI写作软件,它们能够帮助你轻松完成各种写作任务&#xff0c…

人力资源数据集分析(一)_t-test、卡方检验和描述性统计

数据入口:人力资源分析数据集 - Heywhale.com 数据说明 字段说明EmpID唯一的员工IDAge年龄AgeGroup年龄组Attrition是否离职BusinessTravel出差:很少、频繁、不出差DailyRate日薪Department任职部门:研发部门、销售部门、人力资源部门Dista…

文件防泄密软件哪个好?6款被夸爆的文件防泄密软件推荐!

滴水不漏,方显器量;信息无泄,乃见安防。 文件防泄密软件作为保护企业数据安全的重要工具,受到了越来越多企业的关注。 本文将为您推荐六款备受好评的文件防泄密软件,它们各具特色,功能强大,能…

C语言 结构体和共用体——枚举类型

目录 枚举数据类型 三问枚举数据类型 枚举数据类型 三问枚举数据类型

Ubuntu与Windows之间实现复制粘贴

1.卸载已有的工具 sudo apt-get autoremove open-vm-tools 2.安装工具open-vm-tools sudo apt-get install open-vm-tools 3.安装open-vm-tools-desktop sudo apt-get install open-vm-tools-desktop

Virtuoso服务在centos中自动停止的原因分析及解决方案

目录 前言1. 问题背景2. 原因分析2.1 终端关闭导致信号12.2 nohup命令的局限性 3. 解决方案3.1 使用 screen 命令保持会话3.2 使用 tmux 作为替代方案3.3 使用系统服务(systemd) 4. 其他注意事项4.1 网络配置4.2 日志监控 结语 前言 在使用Virtuoso作为…

Jenkins怎么设置每日自动执行构建任务?

在 Jenkins 中设置每日自动执行构建任务可以按照以下步骤进行: 一、安装必要插件 确保安装了 “Timestamper” 插件,这个插件可以为构建添加时间戳,方便查看构建的执行时间。 二、配置任务 打开需要设置每日自动执行的 Jenkins 任务。在 …

《线性代数》常用公式定理总结

文章目录 1 行列式1.1 克拉默法则1.2 基本性质1.3 余子式 M i j M_{ij} Mij​1.4 代数余子式 A i j ( − 1 ) i j ⋅ M i j A_{ij} (-1)^{ij} \cdot M_{ij} Aij​(−1)ij⋅Mij​1.5 具体型行列式计算(化为基本型)1.5.1 主对角线行列式:主…