Springboot-本地缓存(Google Guava Cache)
GuavaCache是Google公司开发⼀种本地缓存机制,之所以叫本地缓存,是因为它不会把缓存数据放到外部⽂件或者其他服务器上,⽽是存放到了应⽤内存中。GuavaCache的优点是简单、强⼤、轻量级。
·
1.Guava Cache简介
Guava Cache是Google公司开发⼀种本地缓存机制,之所以叫本地缓存,是因为它不会把缓存数据放到外部⽂件或者其他服务器上,⽽是存放到了应⽤内存中。
Guava Cache的优点是:简单、强⼤、轻量级。
2.Guava Cache场景
1,接口多次重复查询
2,愿意牺牲一部分内存空间
3,缓存的结果集占内存较小
3. Guava Cache搭建
3.1.依赖管理
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>24.0-jre</version>
</dependency>
3.2.配置Guava缓存管理器
①:@EnableCaching必须得加(开启缓存)
②:创建CacheBuilder并配置属性
package com.yuwenwen.config;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.TimeUnit;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.guava.GuavaCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableCaching
public class CacheConfigration {
@Bean
public CacheManager cacheManager() {
CacheBuilder<Object, Object> ObjectCacheBuilder = CacheBuilder.newBuilder()
// 存活时间(30秒内没有被访问则被移除)
.expireAfterAccess(30, TimeUnit.SECONDS)
// 存活时间(写入10分钟后会自动移除)
.expireAfterWrite(10, TimeUnit.MINUTES)
// 最大size
.maximumSize(1000)
// 最大并发量同时修改
.concurrencyLevel(6)
// 初始化大小为100个键值对
.initialCapacity(100)
// 变成软引用模式(在jvm内存不足时会被回收)
.softValues();
GuavaCacheManager cacheManager = new GuavaCacheManager();
cacheManager.setCacheBuilder(ObjectCacheBuilder);
return cacheManager;
}
}
3.3.编写Service
@CacheConfig
:主要用于配置该类中会用到的一些共用的缓存配置。在这里
@CacheConfig(cacheNames = "users")
:配置了该数据访问对象中返回的内容将存储于名为users的缓存对象中,我们也可以不使用该注解,直接通过@Cacheable
自己配置缓存集的名字来定义。
@Cacheable
:配置了findByName函数的返回值将被加入缓存。同时在查询时,会先从缓存中获取,若不存在才再发起对数据库的访问。该注解主要有下面几个参数:value
、cacheNames
:两个等同的参数(cacheNames
为Spring 4新增,作为value
的别名),用于指定缓存存储的集合名。由于Spring 4中新增了@CacheConfig
,因此在Spring 3中原本必须有的value
属性,也成为非必需项了key
:缓存对象存储在Map集合中的key值,非必需,缺省按照函数的所有参数组合作为key值,若自己配置需使用SpEL表达式,比如:@Cacheable(key = "#p0")
:使用函数第一个参数作为缓存的key值,更多关于SpEL表达式的详细内容可参考官方文档condition
:缓存对象的条件,非必需,也需使用SpEL表达式,只有满足表达式条件的内容才会被缓存,比如:@Cacheable(key = "#p0", condition = "#p0.length() < 3")
,表示只有当第一个参数的长度小于3的时候才会被缓存,若做此配置上面的AAA用户就不会被缓存,读者可自行实验尝试。@CachePut
:配置于函数上,能够根据参数定义条件来进行缓存,它与@Cacheable
不同的是,它每次都会真是调用函数,所以主要用于数据新增和修改操作上。它的参数与@Cacheable
类似,具体功能可参考上面对@Cacheable
参数的解析@CacheEvict
:配置于函数上,通常用在删除方法上,用来从缓存中移除相应数据。除了同@Cacheable
一样的参数之外,它还有下面两个参数:
allEntries
:非必需,默认为false。当为true时,会移除所有数据beforeInvocation
:非必需,默认为false,会在调用方法之后移除数据。当为true时,会在调用方法之前移除数
@Service
public class CacheService {
@CachePut(value = "guavacache",key = "#keyid")
public long save(String keyid) {
long timestamp = System.currentTimeMillis();
System.out.println("进⾏缓存:" + timestamp);
return timestamp;
}
@CacheEvict(value = "guavacache")
public void delete() {
System.out.println("删除缓存");
}
@Cacheable(value = "guavacache")
public long getByCache() {
try {
Thread.sleep(3 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return System.currentTimeMillis();
}
}
3.4.测试疏通
package com.yuwenwen.controller;
import com.yuwenwen.grpc.ApiIn;
import com.yuwenwen.grpc.ApiOut;
import com.yuwenwen.grpc.YuWenWenServiceGrpc.YuWenWenServiceBlockingStub;
import com.yuwenwen.service.CacheService;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/userInfo")
public class UserInfoController {
@GrpcClient("grpc-server")
YuWenWenServiceBlockingStub yuWenWenStub;
@Bean("myExecutor")
public Executor myExecutor() {
// 活动线程数为20的线程池
return Executors.newFixedThreadPool(20);
}
@Autowired
@Qualifier("myExecutor")
Executor executor;
@Autowired
CacheService cacheService;
@RequestMapping(value = "/query")
public String queryUser() {
CompletableFuture<ApiOut> apiOutCompletableFuture = CompletableFuture
.supplyAsync(() -> yuWenWenStub.checkUser(ApiIn.newBuilder().setAge(25).setCode("1124").build()), executor);
return apiOutCompletableFuture.join().getSuccess() ? "successfully" : "failed";
}
/**
* 查询⽅法
*/
@RequestMapping(value = "/get", method = RequestMethod.GET)
public String getByCache() {
Long startTime = System.currentTimeMillis();
long timestamp = this.cacheService.getByCache();
Long endTime = System.currentTimeMillis();
System.out.println("耗时: " + (endTime - startTime));
return timestamp+"";
}
/**
* 保存⽅法
*/
@RequestMapping(value = "/save", method = RequestMethod.POST)
public void save() {
String keyid="yuwenwen";
this.cacheService.save(keyid);
}
/**
* 删除⽅法
*/
@RequestMapping(value = "delete", method = RequestMethod.DELETE)
public void delete() {
this.cacheService.delete();
}
}
Postman
Console
更多推荐
已为社区贡献1条内容
所有评论(0)