一,什么是Spring缓存?
Spring从3.1开始就定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口来统一不同的缓存技术;并支持使用JCache(JSR-107)注解简化我们开发;
Cache接口为缓存的组件规范定义,包含缓存的各种操作集合;
Cache接口下Spring提供了各种xxxCache的实现;如RedisCache,EhCacheCache ,ConcurrentMapCache等;
每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否已经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果后返回给用户。下次调用直接从缓存中获取。
使用Spring缓存抽象时我们需要关注以下两点:
- 确定方法需要被缓存以及他们的缓存策略
- 从缓存中读取之前缓存存储的数据
二,缓存注解
名称 | 解释 |
---|---|
Cache | 缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等 |
CacheManager | 缓存管理器,管理各种缓存(cache)组件 |
@Cacheable | 主要针对方法配置,能够根据方法的请求参数对其进行缓存 |
@CacheEvict | 清空缓存 |
@CachePut | 保证方法被调用,又希望结果被缓存。与@Cacheable区别在于是否每次都调用方法,常用于更新 |
@EnableCaching | 开启基于注解的缓存 |
keyGenerator | 缓存数据时key生成策略 |
serialize | 缓存数据时value序列化策略 |
@CacheConfig | 统一配置本类的缓存注解的属性 |
三,开始使用
工具:IDEA
要在Springboot中使用缓存需要以下几步:
第一步: 导入spring-boot-starter-cache模块和spring-boot-starter-data-redis模块
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
第二步:配置application.properties文件,同时启动redis服务
spring.redis.host=192.168.237.145
spring.redis.port=6379
spring.redis.password=xxxx
spring.redis.database=0
spring.cache.cache-names=c1
第三步: @EnableCaching开启缓存
/**
* @EnableCaching注解是spring framework中的注解驱动的缓存管理功能。自spring版本3.1起加入了该注解。如果你使用了这个注解,
* 那么你就不需要在XML文件中配置cache manager了。
* 当你在配置类(@Configuration)上使用@EnableCaching注解时,会触发一个post processor,这会扫描每一个spring bean,查看是否已经
* 存在注解对应的缓存。如果找到了,就会自动创建一个代理拦截方法调用,使用缓存的bean执行处理。
*/
@SpringBootApplication
@EnableCaching
public class RedisscacheApplication {
public static void main(String[] args) {
SpringApplication.run(RedisscacheApplication.class, args);
}
}
第四步: 创建User实例对象,实现序列化接口
public class User implements Serializable {
private Long id;
private String username;
private String address;
public Long getId() {
return id;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", address='" + address + '\'' +
'}';
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
第五步:创建UserService
/**
* @CacheConfig(cacheNames = "users"):配置了该数据访问对象中返回的内容将存储于名为users的缓存对象中,我们也可以不使用该注解,
* 直接通过@Cacheable自己配置缓存集的名字来定义。
*/
@Service
@CacheConfig(cacheNames = "c1")//主要用于配置该类中会用到的一些共用的缓存配置
public class UserService {
/**
* @Cacheable 注解表示将当前方法执行结果缓存起来,缓存是以 key/value 的形式来缓存,默认缓存的key就是方法的参数,
* 方法的返回值作为value
* @param id
* @return
*/
@Cacheable
public User getUserById(Long id, String name, String address){
System.out.println(">>>>>>>>>>>>>>>...."+id);//这个方法如果事先存在缓存,那么只会执行一次
User user = new User();
user.setId(id);
user.setUsername(name);
user.setAddress(address);
return user;
}
}
第六步:创建测试方法
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisscacheApplicationTests {
@Autowired
UserService userService;
@Test
public void contextLoads() {
User userById = userService.getUserById(1L,"张三","A市");
System.out.println("userById>>>"+userById);
User userById2 = userService.getUserById(2L,"李四","B市");
System.out.println("userById2>>>"+userById2);
}
}
第一次运行结果:
第二次运行结果:
结果表明当两次方法执行的数据是一样的时候,程序默认不再执行相同的方法,直接从缓存数据里查询出结果。