SpringBoot:缓存@EnableCaching

伯向晨
2023-12-01

很多时候系统的瓶颈都在一些比较复杂的IO操作,例如读取数据库,如果一些比较稳定的数据,一般的解决方案就是用缓存。spring boot提供了比较简单的缓存方案。只要使用 @EnableCaching即可完成简单的缓存功能。

缓存的实现有多种实现,ConcurentHashMapCache , GuavaCache, EnCacheCache等多种实现,spring boot 有默认的实现。本文不深入源码解读,首先用起来。 
此处我们模拟要缓存的User

class User {
    private Long id;
    private String name;
// setter getter
}



然后我们业务对象:

import javax.annotation.PostConstruct;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.stereotype.Component;

/**
 * @author micro
 * @date 2017年8月2日
 * @description :
 */
@Component
@EnableCaching
public class UserDao {

    private Map<Long, User> userMap;

    @PostConstruct
    public void init() {
        //模拟数据库
        userMap = new HashMap<Long, User>();
        userMap.put(1L, new User(1L,"micro1"));
        userMap.put(2L, new User(2L, "micro2"));
    }

//注释详解见下个方法注释
    @Cacheable("user")  // 注解key属性可以执行缓存对象user(可以理解为一个map)的key 
    public User getUser(Long userId) {
        System.out.println("查询数据库:userId ->" + userId);
        return userMap.get(userId);
    }

/@Cacheable(value=“nameCache”),这个注释的意思是,当调用这个方法的时候,会从一个名叫 nameCache 的缓存(缓存本质是一个map)中查询key为name的值,如果不存在,则执行实际的方法(即查询数据库等服务逻辑),并将执行的结果存入缓存中,否则返回缓存中的对象。这里的缓存中的 key 就是参数 name,value 就是 返回的User 对象 

    @Cacheable(value = "nameCache", key = "#name")
    public User getUserByName(Long userId, String name) {
        System.out.println("查询数据库:userId ->" + userId);
        return userMap.get(userId);
    }

    @Cacheable("nameCache")
    public User getUserByName(String name) {
        System.out.println("查询数据库:userName : " + name);
        for (Long k : userMap.keySet()) {
            if (userMap.get(k).equals(name)) {
                return userMap.get(k);
            }
        }
        return null;
    }

    @CachePut("user") // 与Cacheable区别就是Cacheable先看缓存如果有,直接缓存换回,CachePut则是每次都会调用并且把返回值放到缓存
    public User getUser2(Long userId) {
        System.out.println("查询数据库:userId : " + userId);
        return userMap.get(userId);
    }

    @CacheEvict("user")
    public void removeFromCache(Long userId) {
        return ;
    }
}

然后我们编写启动类:

@SpringBootApplication
public class CacheTest implements CommandLineRunner {

    @Autowired
    private UserDao userDao;

    public static void main(String[] args) {
        new SpringApplication(CacheTest.class).run(args);
    }

    @Override
    public void run(String... args) throws Exception {
        System.out.println("第一次查询");
        System.out.println(userDao.getUser(1L));
        System.out.println("第二次查询");
        System.out.println(userDao.getUser(1L));
        userDao.removeFromCache(1L);// 移除缓存
        System.out.println("第三次查询");
        userDao.getUser(1L);// 没有缓存了

        System.out.println("--------");
        // 测试不同的key缓存
        userDao.getUserByName("micro1");
        userDao.getUserByName(1L, "micro1");// 指定了参数name 为key 此次读取缓存
    }
}



打印结果:

第一次查询
查询数据库:userId ->1
User@65da01f4
第二次查询
User@65da01f4
第三次查询
查询数据库:userId ->1
--------
查询数据库:userName : micro1



发现能第二次查询拿了缓存,然后我们移除了,第三次又查数据库。然后我们还测试了指定不同参数为key的缓存。

原文参考:https://blog.csdn.net/micro_hz/article/details/76599632

 类似资料: