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是类,而不是基本数据类型。虽…...
LeetCode 1 两数之和
题目描述 链接:https://leetcode.cn/problems/two-sum/?envTypefeatured-list&envId2ckc81c?envTypefeatured-list&envId2ckc81c 难度:简单 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 targ…...
【opencv】windows10下opencv4.8.0-cuda Python版本源码编译教程
【opencv】windows10下opencv4.8.0-cuda Python版本源码编译教程 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【opencv】windows10下opencv4.8.0-cuda Python版本源码编译教程前言准备工具anaconda/cuda/cudnnanaconda创建环境(选做)安装原…...
【1day】用友U8Cloud未授权访问漏洞学习
注:该文章来自作者日常学习笔记,请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与作者无关。 目录 一、漏洞描述 二、影响版本 三、资产测绘 四、漏洞复现...
基于单片机智能汽车仪表设计系统
基于单片机的汽车智能仪表的设计 摘要:汽车的汽车系统。速度测量以及调速是我们这次的设计所要研究的对象,本次设计的基础核心的模块就是单片机,其应用的核心的控制单元就是stc89c52单片机,用到的测速模块是霍尔传感器,…...
java double 保留两位小数
在Java中,你可以使用 DecimalFormat 或 String.format 来保留 double 类型的数字两位小数。以下是两个例子: 使用 DecimalFormat import java.text.DecimalFormat;public class Main {public static void main(String[] args) {double number 123.456…...
计网第六章(应用层)(三)(文件传输协议FTP)
一、基本概念 将某台计算机中的文件通过网络传送到可能相距很远的另一台计算机中即文件传送。 FTP就是因特网上使用得最广泛的文件传送协议。采用客户/服务器方式。 FTP提供交互式的访问,允许客户指明文件的类型和格式(如指明是否使用ASCII码…...
微信小程序canvas画布绘制base64图片并保存图片到相册中
WXML部分: <view class"img_" style"width: 100%;"><canvas type"2d" id"canvasId" style"width: 100%;height: 100%" ></canvas> <button style"margin: auto;width: 70%;marg…...
Hadoop3教程(八):MapReduce中的序列化概述
文章目录 (79)MR序列化概述(80)自定义序列化步骤(81)序列化案例需求分析(82)序列化案例代码参考文献 (79)MR序列化概述 什么是序列化,什么是反序…...
Flash-Attention
这是一篇硬核的优化Transformer的工作。众所周知,Transformer模型的计算量和储存复杂度是 O ( N 2 ) O(N^2) O(N2) 。尽管先前有了大量的优化工作,比如LongFormer、Sparse Transformer、Reformer等等,一定程度上减轻了Transformer的资源消耗…...
发布npm包质量分测试
查询质量分接口 https://registry.npmjs.org/-/v1/search?textcanvas-plus v0.0.1 quality 0.2987 新建文件夹 canvas-plus 执行命令 npm init 生成package.json {"name": "3r/canvas-plus","version": "0.0.1","descript…...
静安手机网站建设/厦门seo关键词优化
一、python环境下 使用循环和随机数造数>>> fpopen("e:\\abc\\1.txt","w")>>> for i in range(50):... fp.write(str(random.randint(13500000000,13999999999))"\n")...>>> fp.close()二、用存储过程࿰…...
网站右侧二维码/外贸独立站怎么建站
P3909 异或之积 题目描述 对于A_1,A_2,A_3,\cdots,A_NA1,A2,A3,⋯,AN,求 (6\times \sum_{i1}^N\sum_{ji1}^N\sum_{kj1}^N A_i\times A_j\times A_k)\ mod\ (10^97)(6∑i1N∑ji1N∑kj1NAiAjAk) mod (1097) 的值。 输入输出格式 输入格式…...
英文网站建设公司报价/深圳专业建站公司
首先要先引用AspNetPager.dll文件 然后在<html>上面添加下面代码: <% Register Assembly"AspNetPager" Namespace"Wuqi.Webdiyer" TagPrefix"webdiyer" %> 然后在repeater控件下添加AspNetPager控件: <web…...
wordpress与新浪博客/军事最新消息
今天使用panelvar包时,显示我的R版本太低,报警告: package panelvar is not available(for R version 3.4.3)对于此类问题解决方法,可以使用以下语句来解决: source("http://bioconductor.org/biocLite.R"…...
做网站需要学会些什么软件/昆明关键词优化
有很多方法可以用来呈现数字, 我们最常用的就是制作一张静态图片. 但你也可以考虑CSS。使用CSS样式化元素来实现数据图表化. 可以使数据的控制更具灵活性。 下面. 你将看到8个CSS技巧. 教你如何使用CSS来制作漂亮、灵活的图表。 1. CSS线条图表数据 这个实例包含了三种图形数…...
寿光人才网招聘网/seo推广系统
本文参考超哥写的 基于 Composer 的 PHP 模块化开发 的详细实践版。 开发痛点 我相信很多人,对 composer 不了解,在开发包的时候会这样做: 创建项目(jcc/new-package) -> 写业务逻辑 -> push 到代码仓库 -> 创建调试项目 -> 安装…...