Spring framework Day14:配置类的Lite模式和Full模式
前言
Lite模式和Full模式是指在软件或系统中的不同配置选项。一般来说,Lite模式是指较为简洁、轻量级的配置,而Full模式则是指更加完整、功能更丰富的配置。
Lite模式通常会去除一些不常用或占用资源较多的功能,以提高系统的运行效率和响应速度。这样可以在资源有限或对系统性能要求较高的情况下使用,比如在低配置的计算设备上或移动设备上。
Full模式则包含了系统或软件的所有功能和特性,同时可能会占用更多的内存和处理器资源。这样可以满足用户对更多功能和高级选项的需求,适合在高配置的计算设备上使用。
选择Lite模式还是Full模式取决于用户的需求和使用场景。如果用户需要更快的响应速度和轻量级的操作体验,或者使用的是资源受限的设备,那么Lite模式可能更适合。而如果用户需要更多功能和高级选项,并且使用的是高配置的设备,那么Full模式可能更适合。
需要注意的是,Lite模式和Full模式的具体配置内容可能因软件或系统而异,用户在选择时应根据具体情况进行判断和比较。
一、开始学习
1、新建项目,结构如下

2、添加 spring 依赖
<!-- spring 的核心依赖 --><dependencies><!-- https://mvnrepository.com/artifact/org.springframework/spring-context --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.23</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.4.5</version></dependency></dependencies>
3、在 service 包下新建一个 UserService 接口,在 impl 包下新建一个 UserServiceImpl 实现类
UserService 接口
public interface UserService {void add();}
UserServiceImpl 实现类
@Slf4j
public class UserServiceImpl implements UserService {@Overridepublic void add() {log.info("添加用户");}
}
4、在 controller 包下新建一个 USerController 类
@RequiredArgsConstructor
public class UserController {private final UserService userService;public void addUser() {userService.add();}}
这段代码使用了Lombok库中的@RequiredArgsConstructor注解,该注解会生成一个带有final修饰的构造方法,用于对类中的final属性进行初始化。在这段代码中,通过使用@RequiredArgsConstructor注解实现了UserController类的构造方法,在构造方法中初始化了userService属性,避免了手动编写构造方法的繁琐。
需要注意的是,使用@RequiredArgsConstructor注解时,必须保证被注解的属性为非空(final)属性,否则在编译时就会出现错误。因此,在使用该注解时,需要仔细检查每一个被注解的属性是否满足要求。
5、在config 包下新建一个 AppConfig 配置类
@Slf4j
@Configuration
public class AppConfig {/*** 装配 Usersevice** @return*/@Beanpublic UserService userService() {return new UserServiceImpl();}/*** 装配 UserController 并注入 UserService** @return*/@Beanpublic UserController userController() {// 得到需要注入的 BeanUserService userService = userService();log.info("1:" + userService);UserService userService1 = userService();log.info("2:" + userService1);// 将 bean 通过构造方法注入return new UserController(userService);}}
这段代码是一个使用Spring框架的Java配置类,其中包含了两个@Bean方法用于将UserService和UserController装配到Spring容器中。
在方法userService()中,使用@Bean注解声明一个UserService的实例,并返回该实例。该方法会在Spring容器启动时被调用,将UserService加入到Spring容器中。
在方法userController()中,同样使用@Bean注解声明一个UserController的实例,并注入一个UserService的实例。在这个方法内部,通过调用userService()方法来获取已经装配到Spring容器中的UserService实例。然后,将得到的UserService实例作为参数传递给UserController的构造方法,创建并返回UserController的实例。
需要注意的是,在这段代码中,还使用了Lombok库中的@Slf4j注解,用于自动生成日志记录器。通过在类上添加该注解,可以在Bean方法中使用log记录日志,避免手动编写日志记录器带来的繁琐。
@Configuration注解是Spring框架中的一个核心注解,用于标识一个类为配置类。配置类主要用于定义和组织Bean的创建和装配过程。具体来说,
@Configuration注解通常与@Bean注解一起使用。在一个带有@Configuration注解的类中,可以使用@Bean注解声明方法,并将该方法返回的对象注册为一个Bean。Spring容器在启动时会扫描这些类,并实例化这些Bean并将其添加到容器中。
6、测试
public class Main {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);UserController bean = context.getBean(UserController.class);bean.addUser();}}
运行结果

此时,可以看到我们输出的 userservice 和 userservice1 的地址是一样的,因为使用了代理模式,使用了 @Configuration 默认情况下,当
proxyBeanMethods设置为true时,Spring容器会将@Bean注解的方法的返回值缓存起来作为单例对象。这样可以确保每次获取该Bean都是同一个实例,提高了性能和一致性。
二、禁用代理模式
1、修改 AppConfig 配置类
@Slf4j
@Configuration(proxyBeanMethods = false)
public class AppConfig {/*** 装配 Usersevice** @return*/@Beanpublic UserService userService() {return new UserServiceImpl();}/*** 装配 UserController 并注入 UserService** @return*/@Beanpublic UserController userController() {// 得到需要注入的 BeanUserService userService = userService();log.info("1:" + userService);UserService userService1 = userService();log.info("2:" + userService1);// 将 bean 通过构造方法注入return new UserController(userService);}}
@Configuration(proxyBeanMethods = false)禁用了代理模式。在这种情况下,Spring容器将不会使用CGLIB动态代理来创建userService()和userController()方法返回的Bean实例。对于
userService()方法,它没有任何依赖关系,每次调用都返回新的UserServiceImpl实例,无需代理。对于
userController()方法,它依赖于userService()方法返回的Bean实例。由于禁用了代理模式,每次调用userService()方法时都会返回一个新的实例,并且这个实例会被注入到UserController的构造方法中。所以,在日志输出中看到的
userService和userService1的值是不同的,它们引用的是不同的UserServiceImpl对象。通过禁用代理模式,您可以确保每个Bean都是原始的实例,并且不存在代理对象的干扰。
2、测试
public class Main {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);UserController bean = context.getBean(UserController.class);bean.addUser();}}
运行结果

3、编译异常

这个警告信息的意思是,您在一个
@Configuration配置类中使用了@Bean注解的方法,并且将proxyBeanMethods设置为false,这可能会导致一些问题。
proxyBeanMethods是@Configuration注解的一个属性,用于指定是否使用代理模式来管理@Bean注解的方法中创建的对象,默认值为true。当设置为true时,Spring容器将使用CGLIB动态代理来管理这些@Bean注解的方法和它们依赖的其他Bean。当设置为false时,Spring容器将直接调用该方法并返回该方法的返回值作为Bean实例。如果您将
proxyBeanMethods设置为false,则表示您不希望使用代理模式来管理Bean,但是同时使用@Bean注解的方法将直接调用,而没有使用Spring容器来管理这些Bean,这可能会导致一些问题。例如,有些Bean之间可能会产生循环依赖问题,导致应用程序无法启动。为了避免这个问题,建议您将
proxyBeanMethods设置为true,或者尽可能使用依赖注入,而不是直接调用@Bean注解的方法。但是呢,并不会影响程序的正常运行。
三、使用代理模式和禁用代理模式的区别
代理模式和禁用代理模式的主要区别在于Spring容器处理@Bean注解的方法时所采用的方式。
当proxyBeanMethods设置为true时,Spring容器会使用CGLIB动态代理来管理@Bean注解的方法和它们之间的依赖关系。
当proxyBeanMethods设置为false时,Spring容器不使用代理,直接调用@Bean注解的方法并返回该方法的返回值作为Bean实例。
1、使用代理模式有以下几个优点:
循环依赖解决:如果存在循环依赖,代理模式可以通过提前暴露代理对象来解决循环依赖问题。代理对象可以在被依赖之前就可以被注入,从而解决了循环依赖的限制。
单例对象缓存:默认情况下,当
proxyBeanMethods设置为true时,Spring容器会将@Bean注解的方法的返回值缓存起来作为单例对象。这样可以确保每次获取该Bean都是同一个实例,提高了性能和一致性。
2、而禁用代理模式则可能会导致以下问题:
循环依赖无法解决:如果存在循环依赖,则会导致应用程序无法启动。
缺少单例对象缓存:由于每次调用
@Bean注解的方法都会返回一个新的实例,因此可能会导致性能问题或意外的行为。
因此,通常情况下建议使用代理模式,并将proxyBeanMethods设置为true,默认就是 true。
四、通过代码了解代理模式
1、在 proxy 包下新建 A、B、BProxy 类
B类
/*** @Date 2023-10-08* @Author qiu** 目标对象(被代理的对象)*/
@Slf4j
public class B {public void say() {log.info("Hello world!");}}
BProxy 类
/*** @Date 2023-10-08* @Author qiu* <p>* 代理对象*/
@Slf4j
public class BProxy {/*** 声明一个被代理的对象*/private B b;public BProxy(B b) {this.b = b;}public void say() {// 目标方法前before();// 调用目标对象的 say 方法b.say();// 目标方法后after();}/*** 调用目标方法前要执行的逻辑*/private void before() {log.info("调用目标之前执行的业务逻辑.....");}private void after() {log.info("调用目标之后执行的业务逻辑.....");}}
2、新建 A 类 测试
public class A {public static void main(String[] args) {// 创建代理对象BProxy bProxy = new BProxy(new B());bProxy.say();}}
运行结果

在这个示例中,
BProxy类是B类的代理类。代理类持有一个被代理对象b的引用,并且在调用say()方法时,会在目标方法前后执行额外的逻辑。
BProxy类中的before()方法和after()方法分别代表了目标方法调用前和调用后需要执行的逻辑。在say()方法中,首先会执行before()方法,然后调用被代理对象b的say()方法,最后再执行after()方法。在
A类的main方法中,创建了一个BProxy对象,并调用其say()方法。由于BProxy是B类的代理类,因此在调用say()方法时,额外的逻辑会被执行。通过静态代理模式,我们可以在不修改原始类
B的情况下,对其进行功能扩展或增强。这种方式可以在一些场景下提供更灵活的控制和定制逻辑。
3、分析,下图

所谓的代理就是可以理解为是一个中间类(中介),当我们需要调用 B 类的方法时,我们通过一个代理类来调用 B 类的方法,为什么需要代理类呢,是因为当我们调用 B 类的方法时需要增加其他的业务逻辑,但是又不能对 B 类去修改,所以使用代理类,在代理类中调用 B 类的方法,并且在代理类中调用 say 方法时,在之前和之后都做了相应业务逻辑处理。而我们用户调用的还是 say 方法,用户不用关心代理类中做了什么事情,它只关注它调用的是它想要的方法即可。
代理类:就是在调用目标对象的方法时,对目标对象的方法进行了增强或者修改。
五、总结
配置类 Lite 模式(非代理模式)和 Full 模式(代理模式)
* 当配置类上标注了 @configuration 注解时,并且 proxyBeanMethods
* 属性设置为 true,此时就是 Full 模式,Full 模式就是 Spring 会为当前
* 配置类创建一个代理对象,从而创建配置类中所有的 @Bean 注解的方法
* 这样每当调用配置类只能的 Bean 方法之前,会从容器中进行检查 Bean 实例,
* 并返回容器中存在的 Bean 对象。
* 反之就是 Lite 模式,Lite 模式下配置类并不会被代理。每次调用 Bean
* 方法只是纯粹的调用,并不会经过代理。
Lite 模式(非代理模式)就是:@Configuration(proxyBeanMethods = false)
Full 模式(代理模式)就是:@Configuration
六、gitee 案例
案例完整地址:https://gitee.com/qiu-feng1/spring-framework.git
相关文章:
Spring framework Day14:配置类的Lite模式和Full模式
前言 Lite模式和Full模式是指在软件或系统中的不同配置选项。一般来说,Lite模式是指较为简洁、轻量级的配置,而Full模式则是指更加完整、功能更丰富的配置。 Lite模式通常会去除一些不常用或占用资源较多的功能,以提高系统的运行效率和响应…...
公司要做大数据可视化看板,除了EXCEL以外有没有好用的软件可以用
当企业需要进行大数据可视化看板的设计和开发时,除了Excel,还有许多其他强大且适合大数据可视化的软件工具。以下是几种常用的好用软件,以及它们的特点和优势,供您参考。 一、Datainside 特点和优势: - **易于使用**…...
掌握深入挖掘数据本质的方法
文章目录 掌握深入挖掘数据本质的方法1. 确定数据类型2. 数据清洗3. 数据可视化4. 探索性数据分析5. 特征工程6. 机器学习算法7. 自然语言处理 📕我是廖志伟,一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华…...
MyBatisPlus的学习项目页面
MyBatisPlus通过扫描实体类,并基于反射获取实体类信息作为数据库表信息 类名驼峰转下划线作为表名 名为id的字段作为主键 变量名驼峰转下划线作为表的字段名 常见注解 TableName:用来指定表名 Tableld:用来指定表中的主键字段信息 Tabl…...
基于EtherCAT的机器人多轴同步运动控制
随着工业自动化的发展,机器人在生产线上的应用越来越广泛。为了实现高效、精确的运动控制,机器人的多轴运动必须能够实现同步操作,它能够提高机器人的运动精度和稳定性,实现更高效的生产线操作。同时,它也为机器人的协…...
彩虹易支付 9.27 最新版加订单查询 sy 更新版
彩虹易支付 9.27 最新版加订单查询 sy 更新版 修复客服 2023/09/25: 1. 新增支付宝红包支付插件 2. 新增支付宝 APP 支付转 H5 支付 3. 更新了几个支付插件 安装教程: 环境:php7.2 上传后访问域名进行安装即可 源码下载:ht…...
python树状打印项目路径
学习这个的需求来自于,我想把项目架构告诉gpt问问它,然后不太会打印项目架构😂 联想到Linux的tree指令 import osclass DirectoryTree:def __init__(self, path):self.path pathdef print_tree(self, methoddefault):if method default:sel…...
mysql误删误操作恢复数据,比传统方式和binlog2sql更快速用的恢复方式-reverse_sql恢复数据(单表多表)
场景: 误操作删除了某个表的数据,本文只讲工具的使用,首先自己通过mysqlbinlog或者记录找到误操作的时间范围:开始时间和结束时间,已经确定好是哪个binlog了下面以误删为例。 查看binlog是否开启 show variables like …...
CORE: Cooperative Reconstruction for Multi-Agent Perception 论文阅读
论文连接 CORE: Cooperative Reconstruction for Multi-Agent Perception 0. 摘要 本文提出了 CORE,一种概念简单、有效且通信高效的多智能体协作感知模型。 从合作重建的新颖角度解决了该任务: 合作主体共同提供对环境的更全面的观察整体观察可以作为…...
MySQL连接方式: Unix套接字 TCP/IP
今天连接mysql数据库使用mysql -u root -p指令的时候遇到了这个问题: 解决之后来总结一下mysql的连接方式 文章目录 1. Unix套接字(或Windows命名管道)特点:场景: 2. TCP/IP特点:场景: 3.对比总…...
TSINGSEE青犀智慧城市数字基座解决方案,助力城市数字化转型
一、行业背景 我国“十四五”规划纲要中提出,分级分类推进新型智慧城市建设,将物联网感知设施、通信系统等纳入公共基础设施统一规划建设,推进市政公用设施、建筑等物联网应用和智能化改造。完善城市信息模型平台和运行管理服务平台…...
【JavaEE】初识网络
网络初识 文章目录 网络初识网络发展史独立模式网络互连局域网LAN广域网 网络通信基础IP地址端口号格式 协议五元组协议分层OSI七层模型TCP/IP五(四)层协议1.物理层2.数据链路层3.网络层4.传输层5.应用程序 网络设备所在的分层封装和分用例子发送方接收方…...
UGUI交互组件ScrollBar
一.ScrollBar的结构 对象说明Scrollbar挂有Image和Scrollbar组件的主体对象Sliding Area表示滑动范围Handle滑块 二.Scrollbar的属性 属性说明Handle Rect控制柄对象的引用Direction拖动控制柄时滚动条值增加的方向Value滚动条的当前值,范围为 0.0 到 1.0Suze控制柄…...
DamiBus v0.51 发布
DamiBus,专为本地多模块之间通讯解耦而设计(尤其是未知模块、隔离模块、领域模块)。零依赖,特适合 DDD。 特点 结合 Bus 与 RPC 的概念,可作事件分发,可作接口调用,可作响应订阅。 支持事务传…...
[OpenJDK:环境变量配置]:填充Profile并修改默认配置
文章目录 一:背景:安装hadoop启动提示未找到JAVA_HOME1.1:配置Hadoop的Java环境变量 二:排查-定位解决2.1:查看环境变量配置发现没有JAVA_HOME2.1.1:解决:查看java安装目录2.1.2:再次…...
连接mysql报错 :Host ‘xxx.xx.x.x‘ is not allowed to connect to this MySQL server
排查思路 命令行连接mysql 我是安装在本地docker容器中的,可以使用一下命令直接连接 docker exec -it mysqldb mysql -u root -p其中mysqldb是我的mysql容器名字,后面跟随mysql的连接命令,然后输入密码即可。 如果没有设置过密码,…...
Qt 布局(QSplitter 类QDockWidget 类) 总结
一、QSplitter 类(窗口分割) QSplitter类是一个Qt框架提供的基础窗口控件类,用于分割窗口,使得用户可以通过拖动分隔条来调节子窗口的大小。QSplitter在用户界面设计中非常常见,经常用于划分窗口区域,使得程序可以同时显示多个子…...
git-ssh-key协议同步文件
生成秘钥 ssh-keygen -t rsa ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/c/Users/Beza/.ssh/id_rsa): /c/Users/Beza/.ssh/id_rsa already exists. Overwrite (y/n)? y Enter passphrase (empty for no passphrase): …...
2018-2019 ACM-ICPC, Asia Nanjing Regional Contest G. Pyramid(组合数学 计数)
题目 t(t<1e6)组样例,每次给定一个n(n<1e9),统计边长为n的上述三角形的等边三角形个数 其中等边三角形的三个顶点,可以在所有黑色三角形&白色三角形的顶点中任取, 答案对1e97取模 思路来源 申老师 & oeis A0003…...
C++学习——string 详解(即C++字符串详解)
以下内容源于C语言中文网的学习与整理,非原创,如有侵权请告知删除。 一、定义string变量的方法 C增强了对字符串的支持,除了可以使用C风格的字符串,还可以使用内置的 string 类。 string是类,而不是基本数据类型。虽…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
