转载自  springboot整合spring @Cache和Redis

spring基于注解的缓存

对于缓存声明,spring的缓存提供了一组java注解:

  • @Cacheable:触发缓存写入。
  • @CacheEvict:触发缓存清除。
  • @CachePut:更新缓存(不会影响到方法的运行)。
  • @Caching:重新组合要应用于方法的多个缓存操作。
  • @CacheConfig:设置类级别上共享的一些常见缓存设置。

@Cacheable注解

顾名思义,@Cacheable可以用来进行缓存的写入,将结果存储在缓存中,以便于在后续调用的时候可以直接返回缓存中的值,而不必再执行实际的方法。 最简单的使用方式,注解名称=缓存名称,使用例子如下:

  @Cacheable("books")public Book findBook(ISBN isbn) {...}

一个方法可以对应两个缓存名称,如下:

    @Cacheable({"books", "isbns"})public Book findBook(ISBN isbn) {...} 

@Cacheable的缓存名称是可以配置动态参数的,比如选择传入的参数,如下: (以下示例是使用SpEL声明,如果您不熟悉SpEL,可以阅读Spring Expression Language)

    @Cacheable(cacheNames="books", key="#isbn")public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)@Cacheable(cacheNames="books", key="#isbn.rawNumber")public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)@Cacheable(cacheNames="books", key="T(someType).hash(#isbn)")public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed) 

@Cacheable还可以设置根据条件判断是否需要缓存

  • condition:取决于给定的参数是否满足条件
  • unless:取决于返回值是否满足条件

以下是一个简单的例子:

    @Cacheable(cacheNames="book", condition="#name.length() < 32") public Book findBook(String name)@Cacheable(cacheNames="book", condition="#name.length() < 32", unless="#result.hardback") public Book findBook(String name) 

@Cacheable还可以设置:keyGenerator(指定key自动生成方法),cacheManager(指定使用的缓存管理),cacheResolver(指定使用缓存的解析器)等,这些参数比较适合全局设置,这里就不多做介绍了。

@CachePut注解

@CachePut:当需要更新缓存而不干扰方法的运行时 ,可以使用该注解。也就是说,始终执行该方法,并将结果放入缓存,注解参数与@Cacheable相同。 以下是一个简单的例子:

    @CachePut(cacheNames="book", key="#isbn")public Book updateBook(ISBN isbn, BookDescriptor descriptor) 

通常强烈建议不要对同一方法同时使用@CachePut和@Cacheable注解,因为它们具有不同的行为。可能会产生不可思议的BUG哦。

@CacheEvict注解

@CacheEvict:删除缓存的注解,这对删除旧的数据和无用的数据是非常有用的。这里还多了一个参数(allEntries),设置allEntries=true时,可以对整个条目进行批量删除。 以下是个简单的例子:

@Caching注解
    @CacheEvict(cacheNames="books") public void loadBooks(InputStream batch)//对cacheNames进行批量删除@CacheEvict(cacheNames="books", allEntries=true) public void loadBooks(InputStream batch)

@Caching:在使用缓存的时候,有可能会同时进行更新和删除,会出现同时使用多个注解的情况.而@Caching可以实现。 以下是个简单的例子:

    @Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0") })public Book importBooks(String deposit, Date date) 

@CacheConfig注解

@CacheConfig:缓存提供了许多的注解选项,但是有一些公用的操作,我们可以使用@CacheConfig在类上进行全局设置。 以下是个简单的例子:

    @CacheConfig("books") public class BookRepositoryImpl implements BookRepository {@Cacheablepublic Book findBook(ISBN isbn) {...}} 

可以共享缓存名称,统一配置KeyGenerator,CacheManager,CacheResolver。

实例

来看看我们在springboot中怎么使用redis来作为缓存吧.

为spring cache配置redis作为缓存

1.在pom.xml引入redis依赖

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

2.springboot集成redis配置文件(在本地启动的redis),在springboot中使用redis,只要配置文件写有redis配置,代码就可以直接使用了。

spring:redis:database: 0 # Database index used by the connection factory.url: redis://user:@127.0.0.1:6379 # Connection URL. Overrides host, port, and password. User is ignored. Example: redis://user:password@example.com:6379host: 127.0.0.1 # Redis server host.password: # Login password of the redis server.port: 6379 # Redis server port.ssl: false # Whether to enable SSL support.timeout: 5000 # Connection timeout. 

3.redis缓存配置类CacheConfig,这里对spring的缓存进行了配置,包括KeyGenerator,CacheResolver,CacheErrorHandler,CacheManager,还有redis序列化方式。

/*** @author wwj*/
@Configuration
public class CacheConfig extends CachingConfigurerSupport {@Resourceprivate RedisConnectionFactory factory;/*** 自定义生成redis-key** @return*/@Override@Beanpublic KeyGenerator keyGenerator() {return (o, method, objects) -> {StringBuilder sb = new StringBuilder();sb.append(o.getClass().getName()).append(".");sb.append(method.getName()).append(".");for (Object obj : objects) {sb.append(obj.toString());}System.out.println("keyGenerator=" + sb.toString());return sb.toString();};}@Beanpublic RedisTemplate<Object, Object> redisTemplate() {RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(factory);GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();redisTemplate.setKeySerializer(genericJackson2JsonRedisSerializer);redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);return redisTemplate;}@Bean@Overridepublic CacheResolver cacheResolver() {return new SimpleCacheResolver(cacheManager());}@Bean@Overridepublic CacheErrorHandler errorHandler() {// 用于捕获从Cache中进行CRUD时的异常的回调处理器。return new SimpleCacheErrorHandler();}@Bean@Overridepublic CacheManager cacheManager() {RedisCacheConfiguration cacheConfiguration =defaultCacheConfig().disableCachingNullValues().serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));return RedisCacheManager.builder(factory).cacheDefaults(cacheConfiguration).build();}
} 

代码使用

测试@Cacheable方法

    @Testpublic void findUserTest() {for (int i = 0; i < 3; i++) {System.out.println("第" + i + "次");User user = userService.findUser();System.out.println(user);}}@Override@Cacheable(value = {"valueName", "valueName2"}, key = "'keyName1'")public User findUser() {System.out.println("执行方法...");return new User("id1", "张三", "深圳", "1234567", 18);} 

执行结果

只有一次输出了'执行方法...',后面直接从缓存获取,不会再进入方法。

第0次
执行方法...
User{id='id1', name='张三', address='深圳', tel='1234567', age=18}
第1次
User{id='id1', name='张三', address='深圳', tel='1234567', age=18}
第2次
User{id='id1', name='张三', address='深圳', tel='1234567', age=18}

测试@CachePut方法:对缓存进行了修改

    @Testpublic void updateUserTest() {userService.updateUser();User user = userService.findUser();System.out.println(user);}@Override@CachePut(value = "valueName", key = "'keyName1'")public User updateUser() {System.out.println("更新用户...");return new User("id1", "李四", "北京", "1234567", 18);} 

执行结果

对缓存进行了更新,获取值的时候取了新的值

更新用户...
User{id='id1', name='李四', address='北京', tel='1234567', age=18}

测试@CacheEvict方法:缓存被清空,再次findUser的时候又重新执行了方法。

    @Testpublic void clearUserTest() {userService.clearUser();User user = userService.findUser();System.out.println(user);}@Override@CacheEvict(value = "valueName",allEntries = true)public void clearUser() {System.out.println("清除缓存...");} 

执行结果

这里清除了缓存,为什么还是没有执行方法呢?因为这个方法我们定了两个value值,清了一个还有一个

清除缓存...
User{id='id1', name='张三', address='深圳', tel='1234567', age=18}

最后贴一下代码吧

User.java

package com.wwj.springboot.model;import java.io.Serializable;/*** @author wwj*/
public class User implements Serializable {public User() {}private String id;private String name;private String address;private String tel;private Integer age;//省略get,set,tostring
}

CacheTest.java

package com.wwj.springboot.cache;import com.wwj.springboot.model.User;
import com.wwj.springboot.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.test.context.junit4.SpringRunner;import javax.annotation.Resource;/*** @author wwj*/
@RunWith(SpringRunner.class)
@SpringBootTest
@EnableCaching
public class CacheTest {@Resourceprivate UserService userService;@Testpublic void findUserTest() {for (int i = 0; i < 3; i++) {System.out.println("第" + i + "次");User user = userService.findUser();System.out.println(user);}}@Testpublic void updateUserTest() {userService.updateUser();User user = userService.findUser();System.out.println(user);}@Testpublic void clearUserTest() {userService.clearUser();User user = userService.findUser();System.out.println(user);}}

UserService.java

package com.wwj.springboot.service;import com.wwj.springboot.model.User;import java.util.List;/*** @author wwj*/
public interface UserService {/*** 获取用户* @return user*/User findUser();/*** 更新用户信息* @return user*/User updateUser();/*** 清除缓存的用户信息*/void clearUser();}

UserServiceImpl.java

package com.wwj.springboot.service.impl;import com.wwj.springboot.model.User;
import com.wwj.springboot.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 wwj*/
@Service
@CacheConfig(cacheNames = "CacheConfigName")
public class UserServiceImpl implements UserService {@Override@Cacheable(value = {"valueName", "valueName2"}, key = "'keyName1'")public User findUser() {System.out.println("执行方法...");return new User("id1", "张三", "深圳", "1234567", 18);}@Override@CachePut(value = "valueName", key = "'keyName1'")public User updateUser() {System.out.println("更新用户...");return new User("id1", "李四", "北京", "1234567", 18);}@Override@CacheEvict(value = "valueName",allEntries = true)public void clearUser() {System.out.println("清除缓存...");}}

springboot整合spring @Cache和Redis相关推荐

  1. springboot整合spring Cache(redis)

    前言 前面有介绍过spring整合redis和redis的一些注意点,在实际开发中,spring cache方便简化的缓存操作的大部分内容.通过注解的方式实现缓存. 阅读前推荐先阅读:redis缓存介 ...

  2. SpringBoot 结合 Spring Cache 操作 Redis 实现数据缓存

    点击上方"后端技术精选",选择"置顶公众号" 技术文章第一时间送达! 作者:超级小豆丁 http://www.mydlq.club/article/55/ 系统 ...

  3. maven整合@data注解_springboot整合spring Cache(redis)

    前言 前面有介绍过spring整合redis和redis的一些注意点,在实际开发中,spring cache方便简化的缓存操作的大部分内容.通过注解的方式实现缓存. 缓存抽象的核心是将缓存应用于Jav ...

  4. SpringBoot整合Spring Data Elasticsearch

    特点: 分布式,无需人工搭建集群(solr就需要人为配置,使用Zookeeper作为注册中心) Restful风格,一切API都遵循Rest原则,容易上手 近实时搜索,数据更新在Elasticsear ...

  5. springBoot整合spring security+JWT实现单点登录与权限管理前后端分离

    在前一篇文章当中,我们介绍了springBoot整合spring security单体应用版,在这篇文章当中,我将介绍springBoot整合spring secury+JWT实现单点登录与权限管理. ...

  6. springBoot整合spring security+JWT实现单点登录与权限管理前后端分离--筑基中期

    写在前面 在前一篇文章当中,我们介绍了springBoot整合spring security单体应用版,在这篇文章当中,我将介绍springBoot整合spring secury+JWT实现单点登录与 ...

  7. SpringBoot 整合 Spring Security 实现安全认证【SpringBoot系列9】

    SpringCloud 大型系列课程正在制作中,欢迎大家关注与提意见. 程序员每天的CV 与 板砖,也要知其所以然,本系列课程可以帮助初学者学习 SpringBooot 项目开发 与 SpringCl ...

  8. spring boot 整合 spring cache 简单使用

    spring boot 整合 spring cache 简单使用 spring cache简介 使用spring cache spring cache简介 Spring 3.1起,提供了基于注解的对C ...

  9. 八、springboot整合Spring Security

    springboot整合Spring Security 简介 Spring Security是一个功能强大且可高度自定义的身份验证和访问控制框架.它是保护基于Spring的应用程序的事实标准. Spr ...

最新文章

  1. Oracle使用技巧----sqlplus Set常用设置
  2. 说说 JAVA 代理模式
  3. 获取android设备唯一编号_android 获取手机设备的唯一码(IMIE )
  4. jQuery Validate验证方法及教程
  5. java线程 对文件copy 可能删除了 报异常_java线程对文件copy可能删除了报异常
  6. libevent中指定使用哪种方法如select
  7. Python基础入门_5面向对象基础
  8. laravel 执行php命令报错PHP Parse error: syntax error, unexpected '=' in的解决方式
  9. 老旗舰华为能用上鸿蒙吗,华为完全开放鸿蒙,未来所有手机都能用鸿蒙系统?...
  10. apache服务器进程配置文件是,apache服务器进程配置文件是
  11. postgresql 9.1 基于wal的 pitr 恢复
  12. sublime php测试,sublime phpcs代码检查配置
  13. ip切换及时刷新交换机的arp表方法
  14. esp32实现万能红外遥控器 基于开源红外码库IREXT
  15. 第十届泰迪杯数据挖掘挑战赛A题解题思路附代码
  16. Laravel文档梳理5、HTTP请求
  17. 【转】几种不同格式的json解析
  18. Android获取超级管理员权限
  19. Moment.js简单使用
  20. 格式化输出编码问题!

热门文章

  1. 数据结构——图-有向图和无向图的邻接表基础
  2. 计算机一级办公软件试题,计算机一级《MS Office》练习题(含答案)
  3. [PAT乙级]1039 到底买不买
  4. [设计模式]工厂方法模式
  5. [剑指offer]面试题5:从尾到头打印链表
  6. 非递归遍历二叉树(算法导论第三版第十章10.4-5)
  7. apache poi斜边框线_如何使用Apache POI在Excel单元格内画斜线(Java)
  8. revit如何根据坐标进行画线_铭成教你如何根据同步带的齿形进行选型
  9. 第三个一千行+500行总结-数据结构C复习--知识点总结3--七到九章
  10. Ubuntu failed to fetch ... hash sum mismatch