精简还是全能?如何在 Full 和 Lite 之间做出最佳选择!关于Configuration注解的Full模式与Lite模式(SpringBoot2)

在这里插入图片描述

  • 🏃‍♂️ 微信公众号: 朕在debugger
  • © 版权: 本文由【朕在debugger】原创、需要转载请联系博主
  • 📕 如果文章对您有所帮助,欢迎关注、点赞、转发和订阅专栏!


前言

关于 @Configuration 注解,相信在座的各位 Javaer 都使用过,且大部分人使用它是直接在配置类上塞一个 @Configuration 就完事了,不会去过多使用它的参数,这期文章是来讲述 @Configuration 注解的一个代理相关的参数 proxyBeanMethod。

回顾

说是讲 proxyBeanMethod 参数,但是注解本身的功能也需要大致过一下,@Configuration 注解是 Spring 框架中的一个核心注解,用于定义配置类。

配置类可以包含定义和生成 SpringBean 的方法。这些方法通过 @Bean 注解进行标记。(默认是单实例的)

同时加上 @Configuration 注解的类也允许定义额外的bean( @Import )或导入其他配置类( @ImportResource )。


文章目录

  • 一、何为 Full 模式?何为 Lite 模式?查看源码辩雌雄
    • Full 模式
    • Lite 模式
  • 二、案例验证
    • 2-1、将 proxyBeanMethods 设置为 true(默认)
    • 2-2、将 proxyBeanMethods 设置为 false
  • 三、何时使用 Full 模式与 Lite 模式?
  • 四、总结


一、何为 Full 模式?何为 Lite 模式?查看源码辩雌雄

说 Full,说 Lite,其实都是在说 proxyBeanMethods 这个参数,也就是代理 bean 的方法。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {@AliasFor(annotation = Component.class)String value() default "";boolean proxyBeanMethods() default true;boolean enforceUniqueMethods() default true;
}

可以看出,proxyBeanMethods 方法返回值是一个 Boolean 值,默认值是 true,什么意思呢?

它的值为 true 时,就是 Full 模式。为 false 时,就是 Lite 模式。

Full 模式

Full 模式是当你在类上使用 @Configuration 注解且没有将 proxyBeanMethods 属性显式设置为 false 时(默认为 true )的模式。

在 Full 模式下,Spring 容器会通过 CGLIB 动态代理技术创建配置类的代理实例。

这样做的目的是保证同一个配置类中对其他 @Bean 方法的调用总是返回相同的实例,即保证 @Bean 方法是以单例的方式被管理的,无论它们被调用多少次。

这对于维护配置类中 Bean 之间的依赖关系非常重要,因为它确保了依赖注入的一致性和 Spring 容器中 Bean 的单例特性。

Lite 模式

Lite 模式是当你在类上使用 @Component、@Service、@Repository 等其他组件注解,或者使用 @Configuration 注解但将 proxyBeanMethods 属性显式设置为 false 时的模式。

在 Lite 模式下,Spring 容器不会创建配置类的 CGLIB 代理。

这意味着,配置类中的 @Bean 方法在每次调用时都会生成一个新的实例(除非你自己在方法内部处理单例逻辑),并且这些方法之间的调用就像普通 Java 方法调用一样,不会被 Spring 容器特别处理。

Lite 模式通常用于轻量级的 Bean 定义,或者当配置类中的 @Bean 方法不需要相互依赖时,可以提高性能,减少资源消耗。

二、案例验证

定义一个配置类,定义了两个Bean:一个数据库连接池(DataSource)和一个 JdbcTemplate,后者依赖于前者。

2-1、将 proxyBeanMethods 设置为 true(默认)

@Configuration(proxyBeanMethods = true) // 默认为true,可以不显式设置
public class AppConfig {// 创建了一个DataSource实例@Beanpublic DataSource dataSource() {return new HikariDataSource();}@Beanpublic JdbcTemplate jdbcTemplate() {// 这里调用了dataSource()方法来获取DataSource实例return new JdbcTemplate(dataSource());}
}

在这个例子中,因为 proxyBeanMethods 设置为 true,当 Spring 调用 jdbcTemplate() 方法来创建 JdbcTemplate Bean 时,内部通过调用 dataSource() 方法得到的 DataSource 实例,将会是同一个实例。

这是因为配置类被 CGLIB 代理,确保了 dataSource() 方法的调用在整个应用上下文中只创建了一个 DataSource 实例,即使它被多次调用。

这对于保证某些 Bean 的单例特性是非常有用的,尤其是当这些 Bean 之间存在依赖关系

2-2、将 proxyBeanMethods 设置为 false

@Configuration(proxyBeanMethods = false)
public class AppConfig {// 创建了一个DataSource实例@Beanpublic DataSource dataSource() {return new HikariDataSource();}@Beanpublic JdbcTemplate jdbcTemplate() {// 这里调用了dataSource()方法来获取DataSource实例return new JdbcTemplate(dataSource());}
}

在这种情况下,每次从配置类中调用 @Bean 方法(如直接在另一个 @Bean 方法内调用或者在应用中通过上下文调用)都将创建一个新的实例。

这会导致额外的资源消耗和初始化开销,尤其是对设计为单例使用的资源密集型 Bean(如数据库连接池)来说。

但是,这种的好处就是不需要为配置类创建 CGLIB代理,所以可以提升启动时间和减少运行时的内存占用。

探究:不使用 CGLIB 代理为何可以提升启动时间和减少运行时的内存占用?

  • 减少类的加载和处理时间:
    当 proxyBeanMethods 设置为 true 时,Spring 会通过 CGLIB 库为每个配置类创建一个子类(代理类)。

    这个过程需要加载额外的类,执行字节码生成和处理,这会增加应用启动时的CPU和内存开销。

    相反,当 proxyBeanMethods 设置为 false 时,Spring 不会创建这些代理类,从而减少了启动阶段的资源消耗。

  • 避免方法拦截开销:
    在使用 CGLIB 代理的配置类中,每次调用 @Bean 标注的方法时,都会通过代理类,这个代理类会检查是否已经为该 Bean 创建了实例,并确保返回的是同一个实例(单例 Bean)。这个检查和拦截过程在运行时会产生额外的开销

    而 proxyBeanMethods=false 意味着 @Bean 方法会被直接调用,不经过代理类,从而避免了这部分开销。

  • 减少内存占用
    减少代理对象的内存占用:为配置类创建代理对象会增加 JVM 堆内存的使用。

    每个代理类实例都需要消耗一定的内存,特别是在大型应用中,可能有大量的配置类,这种内存占用就变得非常可观。

    关闭代理( proxyBeanMethods=false )意味着这部分内存开销可以被省略。

  • 优化 Spring 容器的管理开销:
    不使用 CGLIB 代理简化了 Spring 容器对 Bean 生命周期的管理。

    Spring 容器不需要维护额外的信息来处理配置类的代理逻辑,这可以进一步降低内存使用并简化容器的运行时行为。

三、何时使用 Full 模式与 Lite 模式?

Full 模式适用于复杂的配置场景,其中配置类中的 Bean 之间存在依赖关系,需要确保通过配置类方法调用获取到的 Bean 是单例的。它适合于那些需要充分利用 Spring 框架提供的依赖注入和 Bean 生命周期管理特性的应用。

Lite 模式适用于简单或性能敏感的应用,其中配置类主要用于组织 Bean 定义,而 Bean 之间的依赖关系较为简单或可以通过其他方式(如构造器注入)解决。

总之,proxyBeanMethods属性的设置取决于你的具体需求,是否需要在配置类中保持@Bean方法调用的单例特性。

在大多数情况下,默认的 true 值是合理的,但在某些高性能需求和简单配置的场景下,将其设置为 false 可能会更有利。

四、总结

Full ( proxyBeanMethods = true ) 保证每个 @Bean 方法被调用多少次返回的组件都是单实例的。

Lite ( proxyBeanMethods = false ) 每个 @Bean 方法被调用多少次返回的组件都是新创建的。

存在组件依赖关系则使用 Full 模式(默认)。否则可以使用 Lite 模式。


finally

如果大家觉得本文写得不错,别忘了给个赞哦!同时,如果您有任何疑问或建议,欢迎在评论区留言,让我们一起交流、探讨!

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

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

相关文章

[Python] 深入理解列表和元组

在学习的C语言中有数组可以用来存储数据,那么在Python中是否也有这样的工具呢?接下来让可莉来给大家讲解列表和元组这两个强力工具吧~ 专栏:《Python》 blog:Keven ’ s blog 在 Python 中,列表和元组是两种常用的序列…

Linux系统安装(CentOS Vmware)

学习环境安装 VMware安装 VMware下载&安装 访问官网:https://www.vmware.com 在此处可以选择语言 点击China(简体中文) 点击产品,点击Workstation Pro 下滑,点击下载试用版 下滑找到Workstation 17 Pro for Wi…

【RPA】浅谈RPA技术及其应用

摘要:随着信息技术的飞速发展,企业对于自动化、智能化的需求日益增强。RPA(Robotic Process Automation,机器人流程自动化)技术应运而生,为企业提供了全新的自动化解决方案。本文首先介绍了RPA技术的基本概…

Github 2024-02-09 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-02-09统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目4Go项目2Scala项目1PLpgSQL项目1Ruby项目1HTML项目1Solidity项目1Lua项目1 开源个人理财应用 Mayb…

8868体育助力法甲巴黎圣日耳曼俱乐部 运作球员转会

法甲的巴黎圣日耳曼足球俱乐部是8868的体育助力球队之一,根据法国媒体RMC的消息,巴黎圣日尔曼仍然希望在一月份增强球队的后防实力。虽然之前球队已经从圣保罗引进了20岁的巴西中后卫卢卡斯-贝拉尔多,而这名小将也将会是巴黎圣日耳曼冬窗的一…

ruoyi若依框架SpringSecurity实现分析

系列文章 ruoyi若依框架学习笔记-01 ruoyi若依框架分页实现分析 ruoyi若依框架SpringSecurity实现分析 文章目录 系列文章前言具体分析一、项目中的SpringSecurity版本二、登录认证流程分析三、权限鉴定四、退出登录五、SpringSecurity配置类 总结 前言 在ruoyi-vue若依框…

Java汽车销售管理

技术架构: springboot mybatis Mysql5.7 vue2 npm node 有需要该项目的小伙伴可以私信我你的Q。 功能描述: 针对汽车销售提供客户信息、车辆信息、订单信息、销售人员管理、财务报表等功能,提供经理和销售两种角色进行管理 效果图&…

Seurat - 聚类教程 (1)

设置 Seurat 对象 在本教程[1]中,我们将分析 10X Genomics 免费提供的外周血单核细胞 (PBMC) 数据集。在 Illumina NextSeq 500 上对 2,700 个单细胞进行了测序。可以在此处[2]找到原始数据。 我们首先读取数据。 Read10X() 函数从 10X 读取 cellranger 管道的输出&…

第十六篇【传奇开心果系列】Python的OpenCV库技术点案例示例:图像质量评估

传奇开心果短博文系列 系列短博文目录Python的OpenCV库技术点案例示例短博文系列博文目录前言一、图像质量评估方法和相关函数的介绍二、均方误差示例代码三、峰值信噪比示例代码四、结构相似性指数示例代码五、视频质量评估示例代码六、OpenCV均方根误差计算示例代码七、OpenC…

贵金属交易包括哪些?香港有哪些贵金属交易平台?

随着金融市场的不断发展,贵金属交易作为一种投资方式,越来越受到投资者的关注。贵金属交易不仅具有投资价值,还能够为投资者提供规避风险和保值的工具。本文将介绍贵金属交易的种类和香港的贵金属交易平台。 一、贵金属交易的种类 贵金属交…

运维的利器--监控--zabbix--第一步:建设zabbix

文章目录 准备工作安装要求安装包获取安装环境 安装工作一、zabbix server服务端安装1.安装mysql2.安装zabbix server及配置环境3.设置并访问zabbix页面5.配置自我监控二、被监控端zabbix agent安装三、在服务端中添加被监控端 思维导图 准备工作 安装要求 为啥要确保正常上网…

【Java】苍穹外卖 Day01

苍穹外卖-day01 课程内容 软件开发整体介绍苍穹外卖项目介绍开发环境搭建导入接口文档Swagger 项目整体效果展示: 管理端-外卖商家使用用户端-点餐用户使用当我们完成该项目的学习,可以培养以下能力: 1. 软件开发整体介绍 作为一名软件开…

【C语言】SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)

一、SYSCALL_DEFINE3与系统调用 在Linux操作系统中,为了从用户空间跳转到内核空间执行特定的内核级操作,使用了一种机制叫做"系统调用"(System Call)。系统调用是操作系统提供给程序员访问和使用内核功能的接口。例如&…

Android开发-之屏幕适配

Android开发-之屏幕适配 前言 Android 系统能发展到今天,离不开其开源性,但是随着越来越多的设备接入 Android 系统,并对 Android 系统进行各种各样的定制,导致长期以来出现了各种碎片化严重的问题。例如,Android 屏…

【新书推荐】7.2 while语句

本节必须掌握的知识点: 掌握if语句语法 熟练使用if语句 7.2.1 示例二十三 ■while语句其语法形式: while(表达式) { 语句块; } ●语法解析: 第一步:执行表达式,如果表达式为真,则执行第…

【代码】Processing笔触手写板笔刷代码合集

代码来源于openprocessing,考虑到国内不是很好访问,我把我找到的比较好的搬运过来! 合集 参考:https://openprocessing.org/sketch/793375 https://github.com/SourceOf0-HTML/processing-p5.js/tree/master 这个可以体验6种笔触…

Netty连接通道中的Channel参数模型

ChannelOption(Channel中的连接参数) ChannelOption.SOBACKLOG ChannelOption.SO_BACKLOG对应的是tcp/ip协议listen函数中的backlog参数,服务端处理客户端连接请求是顺序处理的,所以同一时间只能处理一个客户端连接,多个客户端来的时候&…

P1297 [国家集训队] 单选错位 对期望的理解

[国家集训队] 单选错位 - 洛谷 思路: 其实每个位置的得分只和前一个位置有关。 而他们俩的所有情况的期望就是答案的这部分。 ——这是难想的,我期望学的不好。 (题目给的是每种情况的所有位置的和,全加起来是答案&#xff1…

【数据分享】1929-2023年全球站点的逐月平均风速(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、能见度等指标,说到气象数据,最详细的气象数据是具体到气象监测站点的数据! 有关气象指标的监测站点数据,之前我们分享过1929-2023年全球气象站…

ansible shell模块 可以用来使用shell 命令 支持管道符 shell 模块和 command 模块的区别

这里写目录标题 说明shell模块用法shell 模块和 command 模块的区别 说明 shell模块可以在远程主机上调用shell解释器运行命令,支持shell的各种功能,例如管道等 shell模块用法 ansible slave -m shell -a cat /etc/passwd | grep root # 可以使用管道…