Spring Boot 2.x 把 Guava 干掉了选择本地缓存之王 Caffeine(推荐)

环境配置:

  • JDK 版本:1.8
  • Caffeine 版本:2.8.0
  • SpringBoot 版本:2.2.2.RELEASE

一、本地缓存介绍

缓存在日常开发中启动至关重要的作用,由于是存储在内存中,数据的读取速度是非常快的,能大量减少对数据库的访问,减少数据库的压力。

之前介绍过 Redis 这种 NoSql 作为缓存组件,它能够很好的作为分布式缓存组件提供多个服务间的缓存,但是 Redis 这种还是需要网络开销,增加时耗。本地缓存是直接从本地内存中读取,没有网络开销,例如秒杀系统或者数据量小的缓存等,比远程缓存更合适。

二、缓存组件 Caffeine 介绍

按 Caffeine Github 文档描述,Caffeine 是基于 JAVA 8 的高性能缓存库。并且在 spring5 (springboot 2.x) 后,spring 官方放弃了 Guava,而使用了性能更优秀的 Caffeine 作为默认缓存组件。

1、Caffeine 性能

可以通过下图观测到,在下面缓存组件中 Caffeine 性能是其中最好的。

2、Caffeine 配置说明

参数 类型 描述
initialCapacity integer 初始的缓存空间大小
maximumSize long 缓存的最大条数
maximumWeight long 缓存的最大权重
expireAfterAccess duration 最后一次写入或访问后经过固定时间过期
refreshAfterWrite duration 最后一次写入后经过固定时间过期
refreshAfterWrite duration 创建缓存或者最近一次更新缓存后经过固定的时间间隔,刷新缓存
weakKeys boolean 打开 key 的弱引用
weakValues boolean 打开 value 的弱引用
softValues boolean 打开 value 的软引用
recordStats - 开发统计功能

注意:

  • weakValuessoftValues 不可以同时使用。
  • maximumSizemaximumWeight 不可以同时使用。
  • expireAfterWriteexpireAfterAccess 同事存在时,以 expireAfterWrite 为准。

3、软引用与弱引用

  • 软引用: 如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。
  • 弱引用: 弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存
// 软引用
Caffeine.newBuilder().softValues().build();

// 弱引用
Caffeine.newBuilder().weakKeys().weakValues().build();

三、SpringBoot 集成 Caffeine 两种方式

SpringBoot 有俩种使用 Caffeine 作为缓存的方式:

方式一: 直接引入 Caffeine 依赖,然后使用 Caffeine 方法实现缓存。

方式二: 引入 Caffeine 和 Spring Cache 依赖,使用 SpringCache 注解方法实现缓存。

下面将介绍下,这俩中集成方式都是如何实现的。

Spring Boot 基础就不介绍了,推荐看下这个教程:

https://github.com/javastacks/spring-boot-best-practice

四、SpringBoot 集成Caffeine 方式一

1、Maven 引入相关依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <parent>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-parent</artifactId>
 <version>2.2.2.RELEASE</version>
 </parent>

 <groupId>mydlq.club</groupId>
 <artifactId>springboot-caffeine-cache-example-1</artifactId>
 <version>0.0.1</version>
 <name>springboot-caffeine-cache-example-1</name>
 <description>Demo project for Spring Boot Cache</description>

 <properties>
 <java.version>1.8</java.version>
 </properties>

 <dependencies>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <dependency>
 <groupId>com.github.ben-manes.caffeine</groupId>
 <artifactId>caffeine</artifactId>
 </dependency>
 <dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 </dependency>
 </dependencies>

 <build>
 <plugins>
 <plugin>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-maven-plugin</artifactId>
 </plugin>
 </plugins>
 </build>

</project>

2、配置缓存配置类

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;

@Configuration
public class CacheConfig {

 @Bean
 public Cache<String, Object> caffeineCache() {
 return Caffeine.newBuilder()
 // 设置最后一次写入或访问后经过固定时间过期
 .expireAfterWrite(60, TimeUnit.SECONDS)
 // 初始的缓存空间大小
 .initialCapacity(100)
 // 缓存的最大条数
 .maximumSize(1000)
 .build();
 }

}

3、定义测试的实体对象

import lombok.Data;
import lombok.ToString;

@Data
@ToString
public class UserInfo {
 private Integer id;
 private String name;
 private String sex;
 private Integer age;
}

4、定义服务接口类和实现类

UserInfoService

import mydlq.club.example.entity.UserInfo;

public interface UserInfoService {

 /**
 * 增加用户信息
 *
 * @param userInfo 用户信息
 */
 void addUserInfo(UserInfo userInfo);

 /**
 * 获取用户信息
 *
 * @param id 用户ID
 * @return 用户信息
 */
 UserInfo getByName(Integer id);

 /**
 * 修改用户信息
 *
 * @param userInfo 用户信息
 * @return 用户信息
 */
 UserInfo updateUserInfo(UserInfo userInfo);

 /**
 * 删除用户信息
 *
 * @param id 用户ID
 */
 void deleteById(Integer id);

}

UserInfoServiceImpl

import com.github.benmanes.caffeine.cache.Cache;
import lombok.extern.slf4j.Slf4j;
import mydlq.club.example.entity.UserInfo;
import mydlq.club.example.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.HashMap;

@Slf4j
@Service
public class UserInfoServiceImpl implements UserInfoService {

 /**
 * 模拟数据库存储数据
 */
 private HashMap<Integer, UserInfo> userInfoMap = new HashMap<>();

 @Autowired
 Cache<String, Object> caffeineCache;

 @Override
 public void addUserInfo(UserInfo userInfo) {
 log.info("create");
 userInfoMap.put(userInfo.getId(), userInfo);
 // 加入缓存
 caffeineCache.put(String.valueOf(userInfo.getId()),userInfo);
 }

 @Override
 public UserInfo getByName(Integer id) {
 // 先从缓存读取
 caffeineCache.getIfPresent(id);
 UserInfo userInfo = (UserInfo) caffeineCache.asMap().get(String.valueOf(id));
 if (userInfo != null){
 return userInfo;
 }
 // 如果缓存中不存在,则从库中查找
 log.info("get");
 userInfo = userInfoMap.get(id);
 // 如果用户信息不为空,则加入缓存
 if (userInfo != null){
 caffeineCache.put(String.valueOf(userInfo.getId()),userInfo);
 }
 return userInfo;
 }

 @Override
 public UserInfo updateUserInfo(UserInfo userInfo) {
 log.info("update");
 if (!userInfoMap.containsKey(userInfo.getId())) {
 return null;
 }
 // 取旧的值
 UserInfo oldUserInfo = userInfoMap.get(userInfo.getId());
 // 替换内容
 if (!StringUtils.isEmpty(oldUserInfo.getAge())) {
 oldUserInfo.setAge(userInfo.getAge());
 }
 if (!StringUtils.isEmpty(oldUserInfo.getName())) {
 oldUserInfo.setName(userInfo.getName());
 }
 if (!StringUtils.isEmpty(oldUserInfo.getSex())) {
 oldUserInfo.setSex(userInfo.getSex());
 }
 // 将新的对象存储,更新旧对象信息
 userInfoMap.put(oldUserInfo.getId(), oldUserInfo);
 // 替换缓存中的值
 caffeineCache.put(String.valueOf(oldUserInfo.getId()),oldUserInfo);
 return oldUserInfo;
 }

 @Override
 public void deleteById(Integer id) {
 log.info("delete");
 userInfoMap.remove(id);
 // 从缓存中删除
 caffeineCache.asMap().remove(String.valueOf(id));
 }

}

5、测试的 Controller 类

import mydlq.club.example.entity.UserInfo;
import mydlq.club.example.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping
public class UserInfoController {

 @Autowired
 private UserInfoService userInfoService;

 @GetMapping("/userInfo/{id}")
 public Object getUserInfo(@PathVariable Integer id) {
 UserInfo userInfo = userInfoService.getByName(id);
 if (userInfo == null) {
 return "没有该用户";
 }
 return userInfo;
 }

 @PostMapping("/userInfo")
 public Object createUserInfo(@RequestBody UserInfo userInfo) {
 userInfoService.addUserInfo(userInfo);
 return "SUCCESS";
 }

 @PutMapping("/userInfo")
 public Object updateUserInfo(@RequestBody UserInfo userInfo) {
 UserInfo newUserInfo = userInfoService.updateUserInfo(userInfo);
 if (newUserInfo == null){
 return "不存在该用户";
 }
 return newUserInfo;
 }

 @DeleteMapping("/userInfo/{id}")
 public Object deleteUserInfo(@PathVariable Integer id) {
 userInfoService.deleteById(id);
 return "SUCCESS";
 }

}

五、SpringBoot 集成 Caffeine 方式二

1、Maven 引入相关依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <parent>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-parent</artifactId>
 <version>2.2.2.RELEASE</version>
 </parent>

 <groupId>mydlq.club</groupId>
 <artifactId>springboot-caffeine-cache-example-2</artifactId>
 <version>0.0.1</version>
 <name>springboot-caffeine-cache-example-2</name>
 <description>Demo project for Spring Boot caffeine</description>

 <properties>
 <java.version>1.8</java.version>
 </properties>

 <dependencies>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-cache</artifactId>
 </dependency>
 <dependency>
 <groupId>com.github.ben-manes.caffeine</groupId>
 <artifactId>caffeine</artifactId>
 </dependency>
 <dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 </dependency>
 </dependencies>

 <build>
 <plugins>
 <plugin>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-maven-plugin</artifactId>
 </plugin>
 </plugins>
 </build>

</project>

2、配置缓存配置类

@Configuration
public class CacheConfig {

 /**
 * 配置缓存管理器
 *
 * @return 缓存管理器
 */
 @Bean("caffeineCacheManager")
 public CacheManager cacheManager() {
 CaffeineCacheManager cacheManager = new CaffeineCacheManager();
 cacheManager.setCaffeine(Caffeine.newBuilder()
 // 设置最后一次写入或访问后经过固定时间过期
 .expireAfterAccess(60, TimeUnit.SECONDS)
 // 初始的缓存空间大小
 .initialCapacity(100)
 // 缓存的最大条数
 .maximumSize(1000));
 return cacheManager;
 }

}

3、定义测试的实体对象

@Data
@ToString
public class UserInfo {
 private Integer id;
 private String name;
 private String sex;
 private Integer age;
}

4、定义服务接口类和实现类

服务接口

import mydlq.club.example.entity.UserInfo;

public interface UserInfoService {

 /**
 * 增加用户信息
 *
 * @param userInfo 用户信息
 */
 void addUserInfo(UserInfo userInfo);

 /**
 * 获取用户信息
 *
 * @param id 用户ID
 * @return 用户信息
 */
 UserInfo getByName(Integer id);

 /**
 * 修改用户信息
 *
 * @param userInfo 用户信息
 * @return 用户信息
 */
 UserInfo updateUserInfo(UserInfo userInfo);

 /**
 * 删除用户信息
 *
 * @param id 用户ID
 */
 void deleteById(Integer id);

}

服务实现类

import lombok.extern.slf4j.Slf4j;
import mydlq.club.example.entity.UserInfo;
import mydlq.club.example.service.UserInfoService;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.HashMap;

@Slf4j
@Service
@CacheConfig(cacheNames = "caffeineCacheManager")
public class UserInfoServiceImpl implements UserInfoService {

 /**
 * 模拟数据库存储数据
 */
 private HashMap<Integer, UserInfo> userInfoMap = new HashMap<>();

 @Override
 @CachePut(key = "#userInfo.id")
 public void addUserInfo(UserInfo userInfo) {
 log.info("create");
 userInfoMap.put(userInfo.getId(), userInfo);
 }

 @Override
 @Cacheable(key = "#id")
 public UserInfo getByName(Integer id) {
 log.info("get");
 return userInfoMap.get(id);
 }

 @Override
 @CachePut(key = "#userInfo.id")
 public UserInfo updateUserInfo(UserInfo userInfo) {
 log.info("update");
 if (!userInfoMap.containsKey(userInfo.getId())) {
 return null;
 }
 // 取旧的值
 UserInfo oldUserInfo = userInfoMap.get(userInfo.getId());
 // 替换内容
 if (!StringUtils.isEmpty(oldUserInfo.getAge())) {
 oldUserInfo.setAge(userInfo.getAge());
 }
 if (!StringUtils.isEmpty(oldUserInfo.getName())) {
 oldUserInfo.setName(userInfo.getName());
 }
 if (!StringUtils.isEmpty(oldUserInfo.getSex())) {
 oldUserInfo.setSex(userInfo.getSex());
 }
 // 将新的对象存储,更新旧对象信息
 userInfoMap.put(oldUserInfo.getId(), oldUserInfo);
 // 返回新对象信息
 return oldUserInfo;
 }

 @Override
 @CacheEvict(key = "#id")
 public void deleteById(Integer id) {
 log.info("delete");
 userInfoMap.remove(id);
 }

}

5、测试的 Controller 类

import mydlq.club.example.entity.UserInfo;
import mydlq.club.example.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping
public class UserInfoController {

 @Autowired
 private UserInfoService userInfoService;

 @GetMapping("/userInfo/{id}")
 public Object getUserInfo(@PathVariable Integer id) {
 UserInfo userInfo = userInfoService.getByName(id);
 if (userInfo == null) {
 return "没有该用户";
 }
 return userInfo;
 }

 @PostMapping("/userInfo")
 public Object createUserInfo(@RequestBody UserInfo userInfo) {
 userInfoService.addUserInfo(userInfo);
 return "SUCCESS";
 }

 @PutMapping("/userInfo")
 public Object updateUserInfo(@RequestBody UserInfo userInfo) {
 UserInfo newUserInfo = userInfoService.updateUserInfo(userInfo);
 if (newUserInfo == null){
 return "不存在该用户";
 }
 return newUserInfo;
 }

 @DeleteMapping("/userInfo/{id}")
 public Object deleteUserInfo(@PathVariable Integer id) {
 userInfoService.deleteById(id);
 return "SUCCESS";
 }

}

参考地址:

https://www.jianshu.com/p/c72fb0c787fc
https://www.cnblogs.com/rickiyang/p/11074158.html
https://github.com/my-dlq/blog-example/tree/master/springboot/springboot-caffeine-cache-example

到此这篇关于Spring Boot 2.x 把 Guava 干掉了选择本地缓存之王 Caffeine的文章就介绍到这了,更多相关Spring Boot 2.x Caffeine内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解SpringBoot缓存的实例代码(EhCache 2.x 篇)

    本篇介绍了SpringBoot 缓存(EhCache 2.x 篇),分享给大家,具体如下: SpringBoot 缓存 在 spring Boot中,通过@EnableCaching注解自动化配置合适的缓存管理器(CacheManager),Spring Boot根据下面的顺序去侦测缓存提供者: Generic JCache (JSR-107) EhCache 2.x Hazelcast Infinispan Redis Guava Simple 关于 Spring Boot 的缓存机制: 高速

  • 详解spring boot集成ehcache 2.x 用于hibernate二级缓存

    本文将介绍如何在spring boot中集成ehcache作为hibernate的二级缓存.各个框架版本如下 spring boot:1.4.3.RELEASE spring framework: 4.3.5.RELEASE hibernate:5.0.1.Final(spring-boot-starter-data-jpa默认依赖) ehcache:2.10.3 项目依赖 <dependency> <groupId>org.springframework.boot</gro

  • springboot使用GuavaCache做简单缓存处理的方法

    问题背景 实际项目碰到一个上游服务商接口有10秒的查询限制(同个账号). 项目中有一个需求是要实时统计一些数据,一个应用下可能有多个相同的账号.由于服务商接口的限制,当批量查询时,可能出现同一个账号第一次查询有数据,但第二次查询无数据的情况. 解决方案 基于以上问题,提出用缓存的过期时间来解决. 这时,可用Redis和Guava Cache来解决: 当批量查询时,同一个账号第一次查询有数据则缓存并设置过期时间10s, 后续查询时直接从缓存中取,没有再从服务商查询. 最终采用Guava Cache

  • 详解Guava Cache本地缓存在Spring Boot应用中的实践

    概述 在如今高并发的互联网应用中,缓存的地位举足轻重,对提升程序性能帮助不小.而 3.x开始的 Spring也引入了对 Cache的支持,那对于如今发展得如火如荼的 Spring Boot来说自然也是支持缓存特性的.当然 Spring Boot默认使用的是 SimpleCacheConfiguration,即使用 ConcurrentMapCacheManager 来实现的缓存.但本文将讲述如何将 Guava Cache缓存应用到 Spring Boot应用中. Guava Cache是一个全内

  • SpringBoot加入Guava Cache实现本地缓存代码实例

    这篇文章主要介绍了SpringBoot加入Guava Cache实现本地缓存代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在pom.xml中加入guava依赖 <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>18.0</version>

  • Springboot整合GuavaCache缓存过程解析

    这篇文章主要介绍了springboot整合GuavaCache缓存过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Guava Cache是一种本地缓存机制,之所以叫本地缓存,是因为它不会把缓存数据放到外部文件或者其他服务器上,而是存放到了应用内存中. Guava Cache的优点是:简单.强大.轻量级. GuavaCache适用场景: 1.某些接口或者键值会被查询多次以上: 2.愿意使用或牺牲一些内存空间来提升访问或者计算速度: 3.缓

  • Spring Boot 2.x 把 Guava 干掉了选择本地缓存之王 Caffeine(推荐)

    环境配置: JDK 版本:1.8 Caffeine 版本:2.8.0 SpringBoot 版本:2.2.2.RELEASE 一.本地缓存介绍 缓存在日常开发中启动至关重要的作用,由于是存储在内存中,数据的读取速度是非常快的,能大量减少对数据库的访问,减少数据库的压力. 之前介绍过 Redis 这种 NoSql 作为缓存组件,它能够很好的作为分布式缓存组件提供多个服务间的缓存,但是 Redis 这种还是需要网络开销,增加时耗.本地缓存是直接从本地内存中读取,没有网络开销,例如秒杀系统或者数据量小

  • Spring Boot实战解决高并发数据入库之 Redis 缓存+MySQL 批量入库问题

    目录 前言 架构设计 代码实现 测试 总结 前言 最近在做阅读类的业务,需要记录用户的PV,UV: 项目状况:前期尝试业务阶段: 特点: 快速实现(不需要做太重,满足初期推广运营即可)快速投入市场去运营 收集用户的原始数据,三要素: 谁在什么时间阅读哪篇文章 提到PV,UV脑海中首先浮现特点: 需要考虑性能(每个客户每打开一篇文章进行记录)允许数据有较小误差(少部分数据丢失) 架构设计 架构图: 时序图 记录基础数据MySQL表结构 CREATE TABLE `zh_article_count`

  • Spring Boot基础学习之Mybatis操作中使用Redis做缓存详解

    前言 这篇博客学习下Mybatis操作中使用Redis做缓存.这里其实主要学习几个注解:@CachePut.@Cacheable.@CacheEvict.@CacheConfig. 下面话不多说了,来一起看看详细的介绍吧 一.基础知识 @Cacheable @Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存 参数 解释 example value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如: @Cacheable(value="myc

  • 详解Spring Boot Mysql 版本驱动连接池方案选择

    国内环境下,用Mysql还是比较多的.这里简单的总结了一下,如有缪误,还请指正. Mysql.connect 引入mysql-connector-java包,协议为GPL2.0,该协议具有传染性,即:一旦使用(调用)GPL的库,你的软件将被感染为GPL的软件(主程序).完全不具有商业友好特性.如果有顾虑,可以使用mariadb-java-client进行替代,见mariadb-connector-j,路径是org.mariadb.jdbc.Driver 引入JDBC驱动程序 <dependenc

  • 初识Spring Boot框架之Spring Boot的自动配置

    在上篇博客初识Spring Boot框架中我们初步见识了SpringBoot的方便之处,很多小伙伴可能也会好奇这个spring Boot是怎么实现自动配置的,那么今天我就带小伙伴我们自己来实现一个简单的Spring Boot 自动配置的案例,看看这一切到底是怎么发生的. 假设我的需求是这样的:当我的项目中存在某个类的时候,系统自动为我配置该类的Bean,同时,我这个Bean的属性还可以在application.properties中进行配置,OK,就这样一个需求,我们来看看怎么实现. 1.新建s

  • 详解Spring boot Admin 使用eureka监控服务

    前言 最近刚好有空,来学习一下如何搭建spring boot admin环境.其中遇到很多的坑. 网上大多都是使用admin-url的方式直接来监控的,感觉一点也不灵活,这不是我想要的结果,所以本篇介绍借助eureka服务注册和发现功能来灵活监控程序. 本文主要记录spring boot admin的搭建过程,希望能有所帮助.其实非常的简单,不要被使用常规方式的误导! 环境介绍 IDE:intellij idea jdk: java8 maven:3.3.9 spring boot:1.5.6

  • Spring Boot与React集成的示例代码

    前言 前不久学习了Web开发,用React写了前端,Spring Boot搭建了后端,然而没有成功地把两个工程结合起来,造成前端与后端之间需要跨域通信,带来了一些额外的工作. 这一次成功地将前端工程与后端结合在一个Project中,记录一下,也希望能帮到那些和我一样的入门小白. 环境 Windows 10 - x64, Java 1.8.0, node v8.9.4, npm 6.1.0 前奏 *JDK, Node 和 NPM请自行安装 新建一个Spring Boot工程 在Intellij里选

  • 浅谈Spring Boot中如何干掉if else的方法

    前言 看到crossoverJie的文章<利用策略模式优化过多 if else 代码>后受到启发,可以利用策略模式简化过多的if else代码,文章中提到可以通过扫描实现处理器的自注册,我在这里介绍在Spring Boot框架中的实现方法. 需求 这里虚拟一个业务需求,让大家容易理解.假设有一个订单系统,里面的一个功能是根据订单的不同类型作出不同的处理. 订单实体: public class OrderDTO { private String code; private BigDecimal

  • 在Spring Boot中如何使用数据缓存

    在实际开发中,对于要反复读写的数据,最好的处理方式是将之在内存中缓存一份,频繁的数据库访问会造成程序效率低下,同时内存的读写速度本身就要强于硬盘.Spring在这一方面给我们提供了诸多的处理手段,而Spring Boot又将这些处理方式进一步简化,接下来我们就来看看如何在Spring Boot中解决数据缓存问题. 创建Project并添加数据库驱动 Spring Boot的创建方式还是和我们前文提到的创建方式一样,不同的是这里选择添加的依赖不同,这里我们添加Web.Cache和JPA依赖,如下图

随机推荐