当前位置: 首页 > news >正文

Spring Boot实用小技巧 - - 第523篇

《国内最全的Spring Boot系列之一》

《国内最全的Spring Boot系列之二》

《国内最全的Spring Boot系列之三》

《国内最全的Spring Boot系列之四》

《国内最全的Spring Boot系列之五》

《国内最全的Spring Boot系列之六》

《国内最全的Spring Boot系列之七》

Spring的SmartLifecycle可以没用过,但没听过就不好了!- 第517篇

SpringBoot异常处理机制之自定义404、500错误提示页面 - 518篇

SpringBoot 中多例模式的神秘世界:用法区别以及应用场景,最后的灵魂拷问会吗?- 第519篇

SpringBoot开发的AI导航站技术架构剖析 —— 技术如何选型 -  第520篇

SpringBoot多例模式,在同一个类中注入两次是否是同一个对象 – 一不小心就会写出一个重大BUG!!- 521篇

SpringBoot基本原理,轻松应对面试官 - 第522篇

导读

这一节和大家分享一下,Spring Boot的一些小技巧,知道这些小技巧,有助于你在实际项目中解决一些特殊的需求。

技巧一:调整 bean 的加载顺序

调整 bean 的加载顺序的方式有很多种:

(1)可以通过 @Autowired 的方式,让一个 bean 进行初始化

例如: ServiceA 加载之前,一定要初始化 ServiceB,则可以将 ServiceB 通过 @Autowired 时行注入,让 ServiceB 在 ServiceA 之前时行初始化

(2)通过注解@ConditionalOnBean(xxx) 说明这两个Bean的依赖关系。

技巧二:classloader.getResource() 拿不到资源

使用 IDEA 运行 springboot 程序与 java -jar 运行 springboot 程序时 ClassLoader 不同,导致 classloader.getResource() 拿不到资源

使用 this.getClass().getClassLoader() 获取 classloader 时,运行方式不同,结果不一样

使用 IDEA 运行 springboot 程序时,sun.misc.Launcher$AppClassLoader@18b4aac2

使用 java -jar 运行打包后的 jar 包时,org.springframework.boot.loader.LaunchedURLClassLoader@71dac704

LaunchedURLClassLoader 在以下 jar 包依赖中:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-loader</artifactId></dependency>

使用下面的代码,可以拿到类的代码的路径:

如:jar:file:/data/spring-boot-theory.jar!/BOOT-INF/lib/spring-aop-5.0.4.RELEASE.jar!/org/springframework/aop/SpringProxy.class

ProtectionDomain protectionDomain = getClass().getProtectionDomain();CodeSource codeSource = protectionDomain.getCodeSource();URI location = (codeSource == null ? null : codeSource.getLocation().toURI());

对于原始的JarFile URL,只支持一个'!/',SpringBoot 扩展了此协议,使其支持多个'!/',以实现 jar in jar 的加载资源方式。

但是,取到了资源路径,原生的 new File() 还是处理不了这种资源路径的。

我们通过传统的方式取不到资源了,即使取到了,也没法直接使用,那在 SpringBoot 中我们应该怎么获取资源呢?

可以参考 MyBatisPlus 中对 xml 文件的处理:com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties#mapperLocations

技巧三:排除自动配置的几种方式

(1)

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

(2)

@SpringBootApplication(excludeName = "org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration")

(3)配置文件配置

spring:  autoconfigure:     exclude:       - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

技巧四: @ConditionalOnProperty 根据配置加载不同的 bean

场景:对 redis 配置进行封装,实现自动化配置,能兼容哨兵模式和集群模式。

想到在 redis 配置中加一个 redis.type 来区分集群和哨兵模式(redis.type=cluster 或 sentinel),然后根据 type 来分别加载 JedisConnectionFactory、RedisClusterConfiguration、RedisSentinelConfiguration

配置如下:

@ConditionalOnProperty(name = "redis.type", havingValue = "cluster")@ConditionalOnMissingBean@Beanpublic RedisClusterConfiguration redisClusterConfiguration() {}@ConditionalOnProperty(name = "redis.type", havingValue = "sentinel")@ConditionalOnMissingBean@Beanpublic RedisSentinelConfiguration redisSentinelConfiguration() {Set<String> sentinelHostAndPorts = Sets.newHashSet(Splitter.on(",").split(hostName).iterator());RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration(masterName, sentinelHostAndPorts);return redisSentinelConfiguration;}

技巧五: 实现用户行为记录的四种方式

根据产品经理要求,需要对用户的行为进行记录。重点记录用户的姓名、IP、操作行为、请求参数和返回参数。先采用暴力解决问题,每个行为增加记录行为,当然这个是最不恰当的方案,工作量大不说,还不具有扩展性。有4种方案来实现该需求:

(1)AOP切面编程实现:在每一个需要记录日志的方法前增加切点,然后对切点进行处理即可。

(2)Interceptor拦截器实现:定义拦截器类 OperateLogInterceptor 类并实现 HandlerInterceptor 接口。

(3)Filter过滤器实现

(4)ArgumentResolver:参数解析器是 Spring 提供的用于解析自定义参数的工具,使用它,我们可以将参数在进入Controller Action之前就组合成我们想要的样子。

技巧六: 测试中使用随机HTTP端口

在Spring Boot测试中不应该使用静态端口,为了对指定的测试设置该选项,你需要设置 @SpringBootTest 注解中的 webEnvironment 字段,将它的指定为 RANDOM_PORT 而不是默认的 DEFINED_PORT 。配置完后你可以使用 @LocalServerPort 注解将这个随机生成的端口号注入到测试类中。

技巧七:使用@DataJpaTest来测试JPA接口

对于集成测试,通常情况下你可能会使用 @SpringBootTest 来注释测试类,这样做的问题在于它启动了整个应用程序上下文,这会增加运行测试所需的总时间。更好的选择是:你可以使用 @DataJpaTest 来启动JPA组件和带有 @Repository 注解的bean。默认情况下它会在日志中记录SQL查询语句,因此一个好主意是使用 showSql 字段禁用这个特性。此外,如果你希望将带有 @Service 或 @Component 注解的bean包含到测试中,可以使用 @Import 注解。

历史文章(文章累计520+)

《国内最全的Spring Boot系列之一》

《国内最全的Spring Boot系列之二》

《国内最全的Spring Boot系列之三》

《国内最全的Spring Boot系列之四》

《国内最全的Spring Boot系列之五》

《国内最全的Spring Boot系列之六》

《国内最全的Spring Boot系列之七》

抖音主播/电商人员有福了,利用Suno创作产品宣传,让产品动起来-小米Su7 - 第510篇

Spring Boot整合ElasticSearch实战 - 第511篇

Transaction rolled back because it has been marked as - 第512篇

五音不全也浪漫,521清华学霸为爱人写歌 - 第513篇

一文讲清楚SpringBoot项目打包jar后运行报错template might not exist - 第514篇

idea springboot woff/woff2/eot/ttf/svg等小图标不显示的问题 - 第515篇

Noisee AI中文站网页版 AI 音乐生成视频全新登场,快来抢先体验——国内第一个登场的中文站来袭  - 516篇

Spring的SmartLifecycle可以没用过,但没听过就不好了!- 第517篇

SpringBoot异常处理机制之自定义404、500错误提示页面 - 518篇

SpringBoot 中多例模式的神秘世界:用法区别以及应用场景,最后的灵魂拷问会吗?- 第519篇

SpringBoot开发的AI导航站技术架构剖析 —— 技术如何选型 -  第520篇

SpringBoot多例模式,在同一个类中注入两次是否是同一个对象 – 一不小心就会写出一个重大BUG!!- 521篇

SpringBoot基本原理,轻松应对面试官 - 第522篇

http://www.lryc.cn/news/421580.html

相关文章:

  • 安卓App开发 篇二:Android UI和布局
  • k8s基本介绍
  • go http启动应用程序
  • Redis:概念、部署、配置、优化
  • 华为OD-D卷找座位
  • Go sdk下载和配置环境变量
  • qt的项目结构
  • 【NLP】文本特征处理:n-gram特征和文本长度规范
  • ESP32人脸识别开发 ---partitions.csv配置的一些说明(五)
  • 【学习笔记】Matlab和python双语言的学习(图论最短路径)
  • vue.config.js 配置 devserve 配置
  • 不入耳耳机什么牌子性价比高?五大年度必选款揭秘
  • SQL Zoo 6.The JOIN operation
  • 视频教程:Vue3移动端抽屉弹层组件实战
  • CSS 的 BFC(块级格式化上下文)
  • 【2023年】云计算金砖牛刀小试2
  • python--将mysql建表语句转换成hive建表语句
  • 异步调用实践:Async,Future, TaskExecutor、EventListener
  • Flask 异常处理
  • 【海思SS626 | 内存管理】海思芯片的OS内存、MMZ内存设置
  • linux crontab没有按照规则执行排查
  • Cloudflare的D1使用技巧
  • 解决端口号被占用问题
  • 如何在linux上部署zabbix监控工具
  • vulnhub系列:sp eric
  • JVM二:JVM类加载机制
  • 对于springboot无法连接redis解决方案
  • 关于android中的各种尺寸与计算
  • MySQL避免索引失效的方法详细介绍
  • 【Java】深入了解 Java 的 charAt() 方法