Spring Boot 入门示例(十四):Spring Boot 集成 Guava Cache 实现缓存机制

Spring Boot 集成 Guava Cache 实现缓存机制

Guava Cache 是一个全内存的本地缓存实现,而且提供了线程安全机制,相比于数据库或 Redis 存储,访问内存中的数据会更加高效。

Guava 官网介绍,下面的这几种情况可以考虑使用 Guava Cache:

  • 愿意消耗一些内存空间来提升速度。

  • 预料到某些键会被多次查询。

  • 缓存中存放的数据总量不会超出内存容量。

所以,可以将频繁用到的少量数据存储到 Guava Cache 中,以提高程序性能。下面我们来看看 Guava Cache 具体用法。

添加依赖

在 pom.xml 中添加 spring-boot-starter-cacheguava 依赖。

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

<!--guava 依赖-->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>27.0.1-jre</version>
</dependency>

准备数据

模拟数据库的数据

/**
 * 数据工厂,模拟数据库的数据
 *
 * @author star
 **/
public class DataFactory {

    private DataFactory() {
    }

    private static List<UserDto> userDtoList;

    static {
        // 初始化集合
        userDtoList = new ArrayList<>();

        UserDto user = null;
        for (int i = 0; i < 5; i++) {
            user = new UserDto();
            user.setName("star" + i);
            user.setAge(23);
            userDtoList.add(user);
        }
    }

    public static List<UserDto> getUserDaoList() {
        return userDtoList;
    }
}

创建 Guava Cache 配置类

Guava Cache 配置比较简洁,下面配置了缓存数据的过期时间是 10s,最大缓存容量是 1000 个。

@Configuration
@EnableCaching
public class GuavaCacheConfig {

    /**
     * 设置缓存管理器
     */
    @Bean
    public CacheManager cacheManager(){
        GuavaCacheManager cacheManager = new GuavaCacheManager();

        cacheManager.setCacheBuilder(CacheBuilder.newBuilder()
                // 缓存过期时间
                .expireAfterWrite(10, TimeUnit.SECONDS)
                // 缓存最大容量是 1000
                .maximumSize(1000)
        );
        return cacheManager;
    }

}

Guava Cache 除了代码中提到的设置缓存过期时间的策略外,还有其他的策略。下面是 Guava Cache 设置缓存过期时间的策略:

  • expireAfterAccess: 当缓存项在指定的时间段内没有被读或写就会被回收。

  • expireAfterWrite:当缓存项在指定的时间段内没有更新就会被回收,如果我们认为缓存数据在一段时间后数据不再可用,那么可以使用该种策略。

  • refreshAfterWrite:当缓存项上一次更新操作之后的多久会被刷新。

编写业务代码

  • 编写 DAO 层
/**
 * UserRepository
 *
 * @author star
 **/
@Repository
public class UserRepository {

    /**
     * 获取用户信息(此处是模拟的数据)
     */
    public UserDto getUserByName(String username) {
        UserDto user = getUserFromList(username);
        return user;
    }

    /**
     * 从模拟的数据集合中筛选 username 的数据
     */
    private UserDto getUserFromList(String username) {

        List<UserDto> userDaoList = DataFactory.getUserDaoList();
        for (UserDto user : userDaoList) {
            if (Objects.equals(user.getName(), username)) {
                return user;
            }
        }
        return null;
    }
}
  • 编写 Service 层
/**
 * UserService
 *
 * @author star
 **/
@Service
@CacheConfig(cacheNames = "guavaCache") // 声明缓存的名称
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Cacheable(key = "#name")
    public UserDto getUserByName(String name) {
        System.out.println("从数据库中获取数据,而不是读取缓存");
        return userRepository.getUserByName(name);
    }

}

由于在上一篇 Spring Boot 缓存技术 已经对缓存用法做了详细说明,这里就简单介绍一下:

  • @Cacheable: 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存。同时在查询时,会先从缓存中获取,若不存在才再发起对数据库的访问。

  • @CachePut:配置于方法上时,能够根据参数定义条件来进行缓存,其与 @Cacheable 不同的是,它不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中,所以主要用于数据新增和修改操作上。

  • @CacheEvict:配置于方法上时,表示从缓存中移除相应数据。

  • 编写 Controller 层

/**
 * UserResource
 *
 * @author star
 **/
@RestController
@RequestMapping("/api")
public class UserResource {

    @Autowired
    private UserService userService;

    @Autowired
    private CacheManager cacheManager;

    @GetMapping("/users/{name}")
    public ResponseEntity<UserDto> getUser(@PathVariable String name) {
        System.out.println("==================");
        UserDto user = userService.getUserByName(name);
        System.out.println(cacheManager.toString());
        return ResponseEntity.ok(user);
    }
}

演示

通过多次向接口 http://localhost:8080/api/users/star1 GET 数据来观察效果:
get
可以看到缓存的启用和效果如下所示:
result

后记

由于自身能力有限,若有错误或者不当之处,还请大家批评指正,一起学习交流!

GitHub 源码地址:springboot-guava-cache

发布了89 篇原创文章 · 获赞 79 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/oschina_41790905/article/details/103769412