一、概述

缓存(Caching)可以存储经常会用到的信息,这样每次需要的时候,这些信息都是立即可用的。

常用的缓存数据库:

Redis   使用内存存储(in-memory)的非关系数据库,字符串、列表、集合、散列表、有序集合,每种数据类型都有自己的专属命令。另外还有批量操作(bulk operation)和不完全(partial)的事务支持 、发布与订阅、主从复制(master/slave replication)、持久化、脚本(存储过程,stored procedure)。 效率比ehcache低,比数据库要快很多,处理集群和分布式缓存方便,有成熟的方案。如果是大型系统,存在缓存共享、分布式部署、缓存内容很大的,建议用redis。
memcached   使用内存存储的键值缓存,键值之间的映射、创建命令、读取命令、更新命令、删除命令以及其他几个命令。为提升性能而设的多线程服务器。memcache在客户端中实现分布式缓存,通过分布式算法指定目标数据的节点。

ehcache    纯java实现,缓存在内存中,可持久化到硬盘,效率高于memcache;但是缓存共享麻烦,集群分布式应用不方便。如果是单个应用或者对缓存访问要求很高的应用,用ehcache。ehcache也有缓存共享方案,不过是通过RMI或者Jgroup多播方式进行广播缓存通知更新,缓存共享复杂,维护不方便;简单的共享可以,但是涉及到缓存恢复,大数据缓存,则不合适。

二、Spring Cache

Spring 缓存的实现是通过创建一个切面(aspect)并触发Spring缓存注解的切点(pointcut)。根据所使用的注解以及缓存的状态,这个切面会从缓存中获取数据,将数据添加到缓存之中或者从缓存中移除某个值。Spring 能都与多个流行的缓存实现进行集成,实现步骤如下:

1、启用对缓存的支持

  • Java 配置 注解驱动缓存

----@EnableCaching

  • XML 声明的缓存

----<cache:annotation-driven>

2、缓存管理器

缓存管理器是Spring缓存抽象的核心,它能够与多个流行的缓存实现进行集成。Spring3.1配置了五个缓存管理器实现:

  • SimpleCacheManager
  • NoOpCacheManager
  • ConcurrentMapCacheManager(它的缓存存储是基于内存的,所以它的生命周期是与应用关联的,对于生产级别的大型企业级应用程序,这可能并不是理想的选择)
  • CompositeCacheManager(系统同时使用多个缓存管理器集成)
  • EhCacheCacheManager

除了核心的Spring框架,Spring Data又提供了两个缓存管理器:

  • RedisCacheManager
  • GemfireCacheManager

3、为方法添加注解以支持缓存

Spring 提供的四个注解来声明缓存规则:

@Cacheable会条件性地触发对方法的调用,这取决于缓存中是不是已经有了所需要的值。
@CachePut采用了一种更为直接的流程。带有@CachePut注解的方法始终都会被调用,而且它的返回值也会放到缓存中。

@Cacheable 和 @CachePut 一些共有的属性:

value:value属性是必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。主要作用是给 cache 取个名称!个人觉得,主要是为了在Spring 容器中可以更好的管理缓存对象。

condition:调用方法前:如果SPEL表达式的值为false的话,将不会去走缓存。

调用方法后:如果SPEL表达式的值为false的话,将不会将返回值放在缓存中。。

unless:调用方法前:不管SPEL的值是 true 还是 false,都会去缓存中寻找对应的值,如果找到了就返回对应的值。没有找到的话才执行方法。

调用方法后:如果SPEL表达式的值是true的话,将不会将返回值放在缓存中。

key:指定的key的值就是我们要保存到缓存数据库中的key的值,但是这个key的指定有自己的一套方式,如下:

另外,需要说明的是 #result 不能用在@Cacheable 上是因为 #result 表示的是 方法调用的缓存值。但是@Cacheable 可能不走方法,可能不会有返回值。所以就不太适用了。但是!但是!#result 可以用在@Cacheable的 unless 属性上,因为 unless 是在方法返回的时候再判断的,所以一定会有返回值!

@CacheEvict 的一些属性,指定了哪些缓存数目应该被移除:

@CacheEvict 主要用在要移除一个数据条目的时候,同时移除这个数据条目在缓存中的 key 和 value。

@Cacheing

@Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关注解,其中拥有属性:cacheable、put、evict。

  1. @Caching(cacheable=@Cacheable("users"),evict={@CacheEvict("cache2"),@CacheEvict(value="cache3",allEntries=true)})

三、Spring Data Redis

Spring Data Redis包含了多个模板实现,用来完成Redis数据库的数据存取功能。

1、添加依赖

  1. <dependency>
  2. <groupId>org.springframework.data</groupId>
  3. <artifactId>spring-data-redis</artifactId>
  4. <version>1.8.7.RELEASE</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>redis.clients</groupId>
  8. <artifactId>jedis</artifactId>
  9. <version>2.9.0</version>
  10. </dependency>

2、Redis连接工厂

为了创建Spring Data Redis的模板,我们首先需要有一个Redis连接工厂。Spring Data Redis提供了四个连接工厂供我们选择(这些连接工厂在适用上都是相同的):

  • JedisConnectionFactory
  • JredisConnectionFactory
  • LettuceConnectionFactory
  • SrpConnectionFactory

3、RedisTemplate 和 StringRedisTemplate

与其他的Spring Data项目类似,Spring Data Redis以模板的形式提供了较高等级的数据访问方案。Spring Data Redis提供了两个模板:

  • RedisTemplate
  • StringRedisTemplate

RedisTemplate 支持 Object类型 的key 和 Object类型 的value。而StringRedisTemplate则采用更简单粗暴的方式,只支持 String类型 的key 和String类型 的value。

4、缓存管理器

上面提到,缓存管理器是Spring Cache 的核心。Spring Data Redis 有着自己的缓存管理器 RedisCacheManager,下面给出两种Spring Data Redis 配置的方式:

  1. @Configuration
  2. @EnableCaching
  3. @ComponentScan(basePackageClasses = {RedisCacheService.class, CacheDao.class})
  4. public class Config {
  5.  
  6. /*Redis 连接工厂*/
  7. @Bean(name = "redisConnectionFactory")
  8. public JedisConnectionFactory jedisConnectionFactory() {
  9. JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
  10. jedisConnectionFactory.setHostName("127.0.0.1");
  11. jedisConnectionFactory.setPort(6379);
  12. jedisConnectionFactory.setPassword("foobared");
  13. jedisConnectionFactory.afterPropertiesSet();
  14. return jedisConnectionFactory;
  15. }
  16.  
  17. /*RedisTemplate */
  18. @Bean(name = "redisTemplate")
  19. public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
  20. RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
  21. redisTemplate.setConnectionFactory(redisConnectionFactory);
  22. redisTemplate.afterPropertiesSet();
  23. redisTemplate.setKeySerializer(new StringRedisSerializer());
  24. redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
  25. redisTemplate.setHashKeySerializer(new StringRedisSerializer());
  26. return redisTemplate;
  27. }
  28.  
  29. /*Redis 缓存管理器*/
  30. @Bean(name = "cacheManager")
  31. public CacheManager cacheManager(RedisTemplate redisTemplate) {
  32. return new RedisCacheManager(redisTemplate);
  33. }
  34.  
  35. }
  1. <!--连接工厂-->
  2. <bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
  3. <property name="hostName" value="${redis.hostName}"/>
  4. <property name="port" value="${redis.port}"/>
  5. <property name="password" value="${redis.password}"/>
  6. </bean>
  7.  
  8. <!--redisTemplate-->
  9. <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
  10. <property name="connectionFactory" ref="redisConnectionFactory"/>
  11. </bean>
  12.  
  13. <!--cacheManager-->
  14. <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
  15. <constructor-arg ref="redisTemplate"/>
  16. </bean>

5、key 和 value 的序列化器

当某个条目保存到Redis key-value存储的时候,key和value都会使用Redis的序列化器(serializer)进行序列化。Spring Data Redis提供了多个这样的序列化器,包括:

  • GenericToStringSerializer:使用Spring转换服务进行序列化;
  • JacksonJsonRedisSerializer:使用Jackson 1,将对象序列化为JSON;
  • Jackson2JsonRedisSerializer:使用Jackson 2,将对象序列化为JSON;
  • JdkSerializationRedisSerializer:使用Java序列化;
  • OxmSerializer:使用Spring O/X映射的编排器和解排器(marshaler和unmarshaler)实现序列化用于XML序列化;
  • StringRedisSerializer:序列化String类型的key和value。

RedisTemplate会使用JdkSerializationRedisSerializer,这意味着key和value都会通过Java进行序列化。StringRedisTemplate默认会使用StringRedisSerializer。

RedisTemplate 的 key 和 value 经过序列化存储可能会让你觉得奇怪,类似如下:

这是正常的,因为使用的是 java 的序列化,如果想要看起来比较舒服的,可以用 StringRedisSerializer 序列成字符串的样子。

6、API 

Spring Data Redis 提供了一套API 友好的操作Redis,如下:

对 Redis 的操作就不就不细讲了,具体的可以看我学习这方面内容时做的相关的练习,也包括前面内容的一些补充。写的还算详细吧!https://github.com/JMCuixy/SpringRedisData

四、结语

JAVA 框架 Spring Cache For Redis.的更多相关文章

  1. 【Spring】17、spring cache 与redis缓存整合

    spring cache,基本能够满足一般应用对缓存的需求,但现实总是很复杂,当你的用户量上去或者性能跟不上,总需要进行扩展,这个时候你或许对其提供的内存缓存不满意了,因为其不支持高可用性,也不具备持 ...

  2. springboot整合spring @Cache和Redis

    转载请注明出处:https://www.cnblogs.com/wenjunwei/p/10779450.html spring基于注解的缓存 对于缓存声明,spring的缓存提供了一组java注解: ...

  3. Spring Boot(八)集成Spring Cache 和 Redis

    在Spring Boot中添加spring-boot-starter-data-redis依赖: <dependency> <groupId>org.springframewo ...

  4. 使用Spring Cache集成Redis

    SpringBoot 是为了简化 Spring 应用的创建.运行.调试.部署等一系列问题而诞生的产物,自动装配的特性让我们可以更好的关注业务本身而不是外部的XML配置,我们只需遵循规范,引入相关的依赖 ...

  5. Java框架spring Boot学习笔记(六):Spring Boot事务管理

    SpringBoot和Java框架spring 学习笔记(十九):事务管理(注解管理)所讲的类似,使用@Transactional注解便可以轻松实现事务管理.

  6. Java框架spring 学习笔记(十八):事务管理(xml配置文件管理)

    在Java框架spring 学习笔记(十八):事务操作中,有一个问题: package cn.service; import cn.dao.OrderDao; public class OrderSe ...

  7. Java框架spring 学习笔记(十四):注解aop操作

    回见Java框架spring Boot学习笔记(十三):aop实例操作,这里介绍注解aop操作 首先编写一个切入点HelloWorld.java package com.example.spring; ...

  8. Spring Cache For Redis

    一.概述 缓存(Caching)可以存储经常会用到的信息,这样每次需要的时候,这些信息都是立即可用的. 常用的缓存数据库: Redis   使用内存存储(in-memory)的非关系数据库,字符串.列 ...

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

    系统环境: Redis 版本:5.0.7 SpringBoot 版本:2.2.2.RELEASE 参考地址: Redus 官方网址:https://redis.io/ 博文示例项目 Github 地址 ...

随机推荐

  1. JAVA多线程创建与退出过程

    Java多个线程,什么时候被创建,什么时候退出? java程序的入口是什么? java主线程main结束后,是否程序就结束了?C中的(windows,linux)main函数执行完,整个进程结束,其子 ...

  2. 最全的CSS浏览器兼容问题http://www.68design.net/Web-Guide/HTMLCSS/37154-1.html

    最全的CSS浏览器兼容问题 来源:68design.net 作者:邓飞飞 2008年09月23日 14:17 网友评论:7条 点击:71865 CSS 对浏览器的兼容性有时让人很头疼,或许当你了解当中 ...

  3. SonarQube

    代码质量管理 Sonar 是一个用于代码质量管理的开放平台.通过插件机制,Sonar 可以集成不同的测试工具,代码分析工具,以及持续集成工具.与持续集成工具(例如 Hudson/Jenkins 等)不 ...

  4. trigger和triggerHandler的使用

    今天琢磨了好久这个trigger和triggerHandler的用法.在网上搜了好多,不过大都是相互抄袭,毛意思都没有.后来自己做了研究. trigger: 1.可以用来触发事件. <input ...

  5. C#获取电脑硬件信息(CPU ID、主板ID、硬盘ID、BIOS编号)

    最近学习过程中,想到提取系统硬件信息做一些验证,故而对网上提到的利用.NET System.Management类获取硬件信息做了进一步的学习.验证.验证是分别在4台电脑,XP SP3系统中进行,特将 ...

  6. 线程使用方法 锁(lock,Rlock),信号了(Semaphore),事件(Event),条件(Ccndition),定时器(timer)

    2线程的使用方法  (1)锁机制       递归锁           RLock()    可以有无止尽的锁,但是会有一把万能钥匙       互斥锁:           Lock()     ...

  7. 2. select下拉框获取选中的值

    1.获取select选中的value值: $("#select1ID").find("option:selected").val();  --select1ID ...

  8. DDD-002

    项目实践:http://www.cnblogs.com/daoqidelv/p/7499662.html#_label0 https://www.cnblogs.com/lonelyxmas/p/79 ...

  9. git 提交文件到gitee

    1.新建文件夹   打开gitbash  初始化仓库 git.init 2.把要提交的文件copy到文件夹 3.git add. 4.git remote add master(分支)  远程仓库 5 ...

  10. 使用jquery.more.js来实现点击底部更多后, 底部加载出新的数据

    <div class="bus-nav-bar ft12"> <div class="navt bor-r-c pos-rel {if $int == ...