springboot集成本地缓存Caffeine的三种使用方式(小结)
作者:冬风孤立 发布时间:2021-06-29 07:00:40
标签:springboot,本地缓存,Caffeine
第一种方式(只使用Caffeine)
gradle添加依赖
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3'
runtimeOnly 'mysql:mysql-connector-java'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
compile group: 'com.github.ben-manes.caffeine', name: 'caffeine', version: '2.8.4'
// compile('org.springframework.boot:spring-boot-starter-cache')
}
编写配置类
package org.example.base.config;
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;
/**
* @author l
* @date Created in 2020/10/27 11:05
*/
@Configuration
//@EnableCaching
public class CacheConfig {
@Bean(value = "caffeineCache")
public Cache<String, Object> caffeineCache() {
return Caffeine.newBuilder()
// 设置最后一次写入或访问后经过固定时间过期
.expireAfterWrite(60, TimeUnit.SECONDS)
// 初始的缓存空间大小
.initialCapacity(1000)
// 缓存的最大条数
.maximumSize(10000)
.build();
}
@Bean(value = "caffeineCache2")
public Cache<String, Object> caffeineCache2() {
return Caffeine.newBuilder()
// 设置最后一次写入或访问后经过固定时间过期
.expireAfterWrite(120, TimeUnit.SECONDS)
// 初始的缓存空间大小
.initialCapacity(1000)
// 缓存的最大条数
.maximumSize(10000)
.build();
}
}
测试
package org.example.base;
import com.github.benmanes.caffeine.cache.Cache;
import org.example.base.bean.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class BaseApplicationTests {
@Qualifier("caffeineCache")
@Autowired
Cache<String, Object> cache;
@Qualifier("caffeineCache2")
@Autowired
Cache<String, Object> cache2;
@Test
public void test() {
User user = new User(1, "张三", 18);
cache.put("123", user);
User user1 = (User) cache.getIfPresent("123");
assert user1 != null;
System.out.println(user1.toString());
User user2 = (User) cache2.getIfPresent("1234");
System.out.println(user2 == null);
}
}
输出
第二种方式(使用Caffeine和spring cache)
gradle添加依赖
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3'
runtimeOnly 'mysql:mysql-connector-java'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
compile group: 'com.github.ben-manes.caffeine', name: 'caffeine', version: '2.8.4'
compile('org.springframework.boot:spring-boot-starter-cache')
}
编写配置类
package org.example.base.config;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
import java.util.ArrayList;
/**
* @author l
* @date Created in 2020/10/27 11:05
*/
@Configuration
@EnableCaching
public class CacheConfig {
public enum CacheEnum {
/**
* @date 16:34 2020/10/27
* 第一个cache
**/
FIRST_CACHE(300, 20000, 300),
/**
* @date 16:35 2020/10/27
* 第二个cache
**/
SECOND_CACHE(60, 10000, 200);
private int second;
private long maxSize;
private int initSize;
CacheEnum(int second, long maxSize, int initSize) {
this.second = second;
this.maxSize = maxSize;
this.initSize = initSize;
}
}
@Bean("caffeineCacheManager")
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
ArrayList<CaffeineCache> caffeineCaches = new ArrayList<>();
for (CacheEnum cacheEnum : CacheEnum.values()) {
caffeineCaches.add(new CaffeineCache(cacheEnum.name(),
Caffeine.newBuilder().expireAfterWrite(Duration.ofSeconds(cacheEnum.second))
.initialCapacity(cacheEnum.initSize)
.maximumSize(cacheEnum.maxSize).build()));
}
cacheManager.setCaches(caffeineCaches);
return cacheManager;
}
// @Bean("FIRST_CACHE")
// public Cache firstCache(CacheManager cacheManager) {
// return cacheManager.getCache("FIRST_CACHE");
// }
//
// @Bean("SECOND_CACHE")
// public Cache secondCache(CacheManager cacheManager) {
// return cacheManager.getCache("SECOND_CACHE");
// }
}
编写service层
package org.example.base;
import org.example.base.bean.User;
import org.example.base.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class BaseApplicationTests {
@Autowired
private UserService userService;
@Test
public void test() {
User user = new User(123,"jack l",18);
userService.setUser(user);
System.out.println(userService.getUser("123"));
}
}
测试
package org.example.base;
import org.example.base.bean.User;
import org.example.base.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class BaseApplicationTests {
@Autowired
private UserService userService;
@Test
public void test() {
User user = new User(123,"jack l",18);
userService.setUser(user);
System.out.println(userService.getUser("123"));
}
}
输出结果
第三种方式(使用Caffeine和spring cache)
gradle依赖添加同方式二
配置类添加方式同方式二
编写service层
package org.example.base.service.impl;
import org.example.base.bean.User;
import org.example.base.service.UserService;
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;
/**
* @author l
* @date Created in 2020/10/23 14:47
*/
@Service
//@CacheConfig(cacheNames = "SECOND_CACHE",cacheManager = "caffeineCacheManager")
public class UserServiceImpl implements UserService {
/**
* 使用@CachePut注解的方法,一定要有返回值,该注解声明的方法缓存的是方法的返回结果。
* it always causes the
* method to be invoked and its result to be stored in the associated cache
**/
@Override
@CachePut(key = "#user.getId()", value = "SECOND_CACHE", cacheManager = "caffeineCacheManager")
public User setUser(User user) {
System.out.println("已经存储进缓存了");
return user;
}
@Override
@CacheEvict(value = "SECOND_CACHE",cacheManager = "caffeineCacheManager")
public void deleteUser(Integer id) {
System.out.println("缓存删除了");
}
@Override
@Cacheable(key = "#id", value = "SECOND_CACHE", cacheManager = "caffeineCacheManager")
public User getUser(Integer id) {
System.out.println("从数据库取值");
//模拟数据库中的数据
return null;
}
}
测试
package org.example.base;
import org.example.base.bean.User;
import org.example.base.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class BaseApplicationTests {
@Autowired
private UserService userService;
@Test
public void test4(){
User user1 = new User(123, "jack l", 18);
userService.setUser(user1);
System.out.println("从缓存中获取 "+userService.getUser(123));
System.out.println(userService.getUser(123322222));
userService.deleteUser(123);
System.out.println(userService.getUser(123));
}
}
输出结果
来源:https://blog.csdn.net/qq_41921994/article/details/109313445


猜你喜欢
- 桥接模式概述桥接模式(Bridge Pattern)也称为桥梁模式、接口(Interfce)模式或柄体(Handle and Body)模式
- 一、什么是外观模式定义:为子系统中的一组接口提供一个一致的界面,用来访问子系统中的一群接口。外观模式组成:Facade:负责子系统的的封装调
- 一、什么是内存泄露?Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状
- 1基本输入输出 static void main(string[] args) { cons
- Jedis事务我们使用JDBC连接Mysql的时候,每次执行sql语句之前,都需要开启事务;在MyBatis中,也需要使用openSessi
- 这篇文章主要介绍了Java内存模型可见性问题相关解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友
- 首先是“饿了么”导航Tab栏悬浮的效果图。大家可以看到上图中的“分类”、“排序”、“筛选”会悬浮在app的顶部,状态随着ScrollView
- 效果图:为了使图片浏览器左右无限循环滑动 我们要自定义gallery的adapter如果要想自定义adapter首先要了解这几个方法@Ove
- \r与\n到底有何区别,编码的时候又应该如何使用,我们下面来了解一下。区别:\r:全称:carriage return (carriage是
- 在Struts2中Action部分,也就是Controller层采用了低侵入的方式。为什么这么说?这是因为在Struts2中action类并
- 【程序1】题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?1.程序分析:可填在百位、十位、个位的数字都是1
- 本篇随笔将讲解一下Android当中比较常用的两个布局容器--ScrollView和HorizontalScrollView,从字面意义上来
- 1.easy-captcha工具包生成验证码的方式有许多种,这里选择的是easy-captcha工具包。github开原地址为:easy-c
- 众所周知,一般情况下我们使用android中的monkeyrunner进行自动化测试时,使用的是python语言来写测试脚本。不过,最近发现
- 本文将通过阅读spring源码,分析@Bean注解导入Bean的原理。从AnnotationConfigApplicationContext
- 本文实例讲述了C#实现的ZPL条码打印类。分享给大家供大家参考,具体如下:using System;using System.Collect
- Kotlin的对象表达式与Java中的匿名内部类的主要区别:匿名内部类只能指定一个父类型,但对象表达式可以指定0~N个肤类型。一、对象表达式
- 我们知道多线程因为同时处理子线程的能力,对于程序运行来说,能够达到很高的效率。不过很多人对于多线程的执行方法还没有尝试过,本篇我们将为大家介
- 本文实例讲述了Java针对封装数组的简单复杂度分析方法。分享给大家供大家参考,具体如下:完成了数组的封装之后我们还需对其进行复杂度分析:此处
- C#申请一个大数组(Use a large array in C#)在C#里,有时候我需要能够申请一个很大的数组、使用之、然后立即释放其占用