SpringBoot 学习记录(七): Redis
来源:互联网 发布:金泫雅的舞蹈 知乎 编辑:程序博客网 时间:2024/05/17 07:58
之前写过一篇spring+spring_mvc+redis的博客,这篇我们学习在spring_boot中如何使用redis
对spring_boot有过了解后可以知道,spring_boot本身集成了很多模块,根据需要引入即可,
redis的使用也是,第一步是引入相关依赖包。
一,pom.xml中添加依赖:
<!-- redis --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> </dependency>二,在application.properties中添加redis的配置,
请确保你的本地已安装有redis,我的是装在虚拟机,
有需要的可以回顾博文:常用框架(二) : spring+springMvc+mybatis+maven+redis
#redisspring.redis.database=0 spring.redis.host=192.168.230.130spring.redis.port=6379 spring.redis.password= spring.redis.pool.max-active=8 spring.redis.pool.max-wait=-1 spring.redis.pool.max-idle=8 spring.redis.pool.min-idle=0 spring.redis.timeout=0
三,定义RedisConfiguration配置类
package com.example.config;import java.lang.reflect.Method;import org.springframework.cache.CacheManager;import org.springframework.cache.annotation.EnableCaching;import org.springframework.cache.interceptor.KeyGenerator;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.cache.RedisCacheManager;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;import com.fasterxml.jackson.annotation.JsonAutoDetect;import com.fasterxml.jackson.annotation.PropertyAccessor;import com.fasterxml.jackson.databind.ObjectMapper;@Configuration@EnableCaching//启用缓存public class RedisConfiguration extends CachingConfigurerSupport {/** * 自定义缓存key值 * 此方法将会根据类名+方法名+所有参数的值生成唯一的一个key */@Beanpublic KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); } }; }/** * 缓存管理器 * @param redisTemplate * @return */ @Bean public CacheManager cacheManager(RedisTemplate<?,?> redisTemplate) { RedisCacheManager rcm = new RedisCacheManager(redisTemplate); //设置缓存过期时间 rcm.setDefaultExpiration(300);//秒 return rcm; } /** * RedisTemplate缓存操作类,类似于jdbcTemplate的一个类; * @param factory * @return */ @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { StringRedisTemplate template = new StringRedisTemplate(factory); //key序列化方式 Jackson2JsonRedisSerializer<Object> redisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); redisSerializer.setObjectMapper(om); template.setValueSerializer(redisSerializer); template.afterPropertiesSet(); return template; }}
四,测试
首先请确保开启你的redis服务:
新建测试类RedisController:
这里我们使用RedisTemplate的api进行存储数据,如下:
一般是自己定义一个RedisService工具类,方便使用,本例就不说明了,有兴趣的可以查看之前的博客。
package com.example.controller;import javax.annotation.Resource;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.ValueOperations;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class RedisController { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Resource private RedisTemplate<String,String> redisTemplate; @RequestMapping("/redis/set") public String setKeyAndValue(){String key = "name";String value = "wendy"; logger.info("访问set:key={},value={}",key,value); ValueOperations<String,String> valOpsStr = redisTemplate.opsForValue(); valOpsStr.set(key, value); return "Set Ok"; } @RequestMapping("redis/get") public String getKey(){ String key = "name"; logger.info("访问get:key={}",key); ValueOperations<String,String> valOpsStr = redisTemplate.opsForValue(); return valOpsStr.get(key); } }启动服务测试:http://localhost:8088/spring-boot/redis/set ===== 返回结果:Set Ok
如果测试redis连接失败,clean project 之后重启再试,如果还有问题,请确保你的redis服务是否开启,配置是否正确等
启动服务测试:http://localhost:8088/spring-boot/redis/get ====== 返回结果:wendy
==================================================================================================
上面定义RedisConfiguration配置类时,我们定义了一个自动生成key的方法,
也就是说不用定义一个唯一key,也能根据自动生成的key存取value值,下面我们来学习如何使用注解的方式
前面学习jap的时候我们定义了UserInfoRepository,在controller层也是直接使用的dao层,
这里我们加上service,使代码规范化
package com.example.service;import com.example.entity.UserInfo;public interface UserService {UserInfo findById(long id);void deleteFromCache(long id);}
package com.example.service.impl;import javax.annotation.Resource;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Service;import com.example.entity.UserInfo;import com.example.repository.UserInfoRepository;import com.example.service.UserService;@Servicepublic class UserServiceImpl implements UserService {private Logger logger = LoggerFactory.getLogger(this.getClass());@Resourceprivate UserInfoRepository userRepository;@Overridepublic UserInfo findById(long id) {logger.info("从数据库查询数据");return userRepository.findById(id);}@Overridepublic void deleteFromCache(long id) {logger.info("从缓存中删除数据");}}五,在RedisController中添加测试方法:
package com.example.controller;import javax.annotation.Resource;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.Cacheable;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.ValueOperations;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import com.example.base.ReturnResult;import com.example.entity.UserInfo;import com.example.service.UserService;@RestControllerpublic class RedisController { @Resource private UserService userService; @RequestMapping("redis/get/user") @Cacheable(value="userInfo")//注解直接缓存查询结果 public UserInfo getUserById(long id){ UserInfo user = userService.findById(id); return user; } @RequestMapping("redis/del/user") @CacheEvict(value="userInfo",allEntries=true)//注解从缓存删除结果 public String delUserById(long id){ userService.deleteFromCache(id); return "del from cache"; }}
这里说明一下spring cache的注解使用:
Cacheable 支持如下几个参数:
value:缓存位置名称,不能为空,如果使用EHCache,就是ehcache.xml中声明的cache的name
key:缓存的key,默认为空则表示使用方法的参数类型及参数值作为key,可以自定义key的生成规则
condition:触发条件,只有满足条件的情况才会加入缓存,默认为空示全部都加入缓存
@CacheEvict 支持如下几个参数:
value:缓存位置名称,不能为空,同上
key:缓存的key,默认为空,同上
condition:触发条件,只有满足条件的情况才会清除缓存,默认为空
allEntries:true表示清除value中的全部缓存,默认为false
================ 注解用在service层是一样的,看个人业务需求使用
访问测试:http://localhost:8088/spring-boot/redis/get/user?id=1
返回结果:
{ "id": 1, "name": "initname", "gender": "F", "status": null}查看控制台:
2017-04-11 14:58:40.609 DEBUG 6308 --- [nio-8088-exec-2] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/spring-boot/redis/get/user]2017-04-11 14:58:40.610 DEBUG 6308 --- [nio-8088-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /redis/get/user2017-04-11 14:58:40.610 DEBUG 6308 --- [nio-8088-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public com.example.entity.UserInfo com.example.controller.RedisController.getUserById(long)]2017-04-11 14:58:40.610 DEBUG 6308 --- [nio-8088-exec-2] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/spring-boot/redis/get/user] is: -12017-04-11 14:58:40.619 INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop : LogAop.doBefore()2017-04-11 14:58:40.619 INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop : URL : http://localhost:8088/spring-boot/redis/get/user2017-04-11 14:58:40.619 INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop : HTTP_METHOD : GET2017-04-11 14:58:40.619 INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop : IP : 0:0:0:0:0:0:0:12017-04-11 14:58:40.622 INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop : CLASS_METHOD : com.example.controller.RedisController.getUserById2017-04-11 14:58:40.623 INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop : ARGS : [1]id: 12017-04-11 14:58:40.724 INFO 6308 --- [nio-8088-exec-2] c.example.service.impl.UserServiceImpl : 从数据库查询数据Hibernate: select userinfo0_.id as id1_0_, userinfo0_.gender as gender2_0_, userinfo0_.name as name3_0_ from user_info userinfo0_ where userinfo0_.id=?2017-04-11 14:58:40.900 INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop : LogAop.doAfter()2017-04-11 14:58:40.900 INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop : LogAop.doAfterReturning()2017-04-11 14:58:40.900 INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop : 耗时(毫秒) : 2812017-04-11 14:58:40.909 DEBUG 6308 --- [nio-8088-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Written [com.example.entity.UserInfo@4f696c3f] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@403a7b03]2017-04-11 14:58:40.910 DEBUG 6308 --- [nio-8088-exec-2] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling2017-04-11 14:58:40.911 DEBUG 6308 --- [nio-8088-exec-2] o.s.web.servlet.DispatcherServlet : Successfully completed request
再次访问,此时应该是从缓存获取数据,控制台不会打印出“从数据库查询数据”这条日志
且注意查看耗时时间,会比查询数据库要短
清除控制台再次访问查看:
2017-04-11 15:19:11.792 DEBUG 6260 --- [nio-8088-exec-3] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/spring-boot/redis/get/user]2017-04-11 15:19:11.793 DEBUG 6260 --- [nio-8088-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /redis/get/user2017-04-11 15:19:11.794 DEBUG 6260 --- [nio-8088-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public com.example.entity.UserInfo com.example.controller.RedisController.getUserById(long)]2017-04-11 15:19:11.794 DEBUG 6260 --- [nio-8088-exec-3] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/spring-boot/redis/get/user] is: -12017-04-11 15:19:11.795 INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop : LogAop.doBefore()2017-04-11 15:19:11.795 INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop : URL : http://localhost:8088/spring-boot/redis/get/user2017-04-11 15:19:11.795 INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop : HTTP_METHOD : GET2017-04-11 15:19:11.796 INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop : IP : 0:0:0:0:0:0:0:12017-04-11 15:19:11.796 INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop : CLASS_METHOD : com.example.controller.RedisController.getUserById2017-04-11 15:19:11.796 INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop : ARGS : [1]id: 12017-04-11 15:19:11.797 INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop : LogAop.doAfter()2017-04-11 15:19:11.797 INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop : LogAop.doAfterReturning()2017-04-11 15:19:11.797 INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop : 耗时(毫秒) : 22017-04-11 15:19:11.803 DEBUG 6260 --- [nio-8088-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Written [com.example.entity.UserInfo@9e8e466] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@345a0792]2017-04-11 15:19:11.803 DEBUG 6260 --- [nio-8088-exec-3] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling2017-04-11 15:19:11.803 DEBUG 6260 --- [nio-8088-exec-3] o.s.web.servlet.DispatcherServlet : Successfully completed request============= 说明测试缓存成功
下面我们测试删除缓存方法:http://localhost:8088/spring-boot/redis/del/user?id=1
返回结果:del from cache
再次测试查询方法:http://localhost:8088/spring-boot/redis/get/user?id=1
可以看到这里又打印了日志:“从数据库查询数据”,删除缓存成功
2017-04-11 21:20:07.644 DEBUG 8460 --- [nio-8088-exec-9] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/spring-boot/redis/del/user]2017-04-11 21:20:07.645 DEBUG 8460 --- [nio-8088-exec-9] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /redis/del/user2017-04-11 21:20:07.645 DEBUG 8460 --- [nio-8088-exec-9] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public java.lang.String com.example.controller.RedisController.delUserById(long)]2017-04-11 21:20:07.646 DEBUG 8460 --- [nio-8088-exec-9] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/spring-boot/redis/del/user] is: -12017-04-11 21:20:07.647 INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop : LogAop.doBefore()2017-04-11 21:20:07.647 INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop : URL : http://localhost:8088/spring-boot/redis/del/user2017-04-11 21:20:07.647 INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop : HTTP_METHOD : GET2017-04-11 21:20:07.648 INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop : IP : 0:0:0:0:0:0:0:12017-04-11 21:20:07.648 INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop : CLASS_METHOD : com.example.controller.RedisController.delUserById2017-04-11 21:20:07.648 INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop : ARGS : [1]id: 12017-04-11 21:20:07.648 INFO 8460 --- [nio-8088-exec-9] c.example.service.impl.UserServiceImpl : 从缓存中删除数据2017-04-11 21:20:07.651 INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop : LogAop.doAfter()2017-04-11 21:20:07.651 INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop : LogAop.doAfterReturning()2017-04-11 21:20:07.651 INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop : 耗时(毫秒) : 42017-04-11 21:20:07.653 DEBUG 8460 --- [nio-8088-exec-9] m.m.a.RequestResponseBodyMethodProcessor : Written [del from cache] as "text/plain;charset=UTF-8" using [org.springframework.http.converter.StringHttpMessageConverter@3badefd6]2017-04-11 21:20:07.653 DEBUG 8460 --- [nio-8088-exec-9] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling2017-04-11 21:20:07.654 DEBUG 8460 --- [nio-8088-exec-9] o.s.web.servlet.DispatcherServlet : Successfully completed request2017-04-11 21:20:10.258 DEBUG 8460 --- [io-8088-exec-10] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/spring-boot/redis/get/user]2017-04-11 21:20:10.259 DEBUG 8460 --- [io-8088-exec-10] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /redis/get/user2017-04-11 21:20:10.259 DEBUG 8460 --- [io-8088-exec-10] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public com.example.entity.UserInfo com.example.controller.RedisController.getUserById(long)]2017-04-11 21:20:10.259 DEBUG 8460 --- [io-8088-exec-10] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/spring-boot/redis/get/user] is: -12017-04-11 21:20:10.263 INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop : LogAop.doBefore()2017-04-11 21:20:10.263 INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop : URL : http://localhost:8088/spring-boot/redis/get/user2017-04-11 21:20:10.263 INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop : HTTP_METHOD : GET2017-04-11 21:20:10.263 INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop : IP : 0:0:0:0:0:0:0:12017-04-11 21:20:10.263 INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop : CLASS_METHOD : com.example.controller.RedisController.getUserById2017-04-11 21:20:10.263 INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop : ARGS : [1]id: 12017-04-11 21:20:10.265 INFO 8460 --- [io-8088-exec-10] c.example.service.impl.UserServiceImpl : 从数据库查询数据Hibernate: select userinfo0_.id as id1_0_, userinfo0_.gender as gender2_0_, userinfo0_.name as name3_0_ from user_info userinfo0_ where userinfo0_.id=?2017-04-11 21:20:10.269 INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop : LogAop.doAfter()2017-04-11 21:20:10.270 INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop : LogAop.doAfterReturning()2017-04-11 21:20:10.270 INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop : 耗时(毫秒) : 72017-04-11 21:20:10.274 DEBUG 8460 --- [io-8088-exec-10] m.m.a.RequestResponseBodyMethodProcessor : Written [com.example.entity.UserInfo@1e076014] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@51e330c]2017-04-11 21:20:10.274 DEBUG 8460 --- [io-8088-exec-10] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling2017-04-11 21:20:10.275 DEBUG 8460 --- [io-8088-exec-10] o.s.web.servlet.DispatcherServlet : Successfully completed request
============================================================================
接下来我们学习如何在redis中存储session,在做负载均衡的时候多应用共享session
一,添加依赖:
<dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId></dependency>
二,定义配置类SessionConfiguration
package com.example.config;import org.springframework.context.annotation.Configuration;import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;@Configuration@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 60*60*2)public class SessionConfiguration {}
接下来就可以部署测试了,这里不做演示
到此redis的学习就暂时告一段落,下篇我们将学习,SpringBoot 学习记录(八): properties 属性自定义
- SpringBoot 学习记录(七): Redis
- springboot学习笔记(七) Redis
- Redis学习记录之命令KEY(七)
- SpringBoot 学习记录(七)- 连接Mysql数据库
- SpringBoot学习:整合Redis
- springboot(七)redis 实现session共享
- springboot学习记录一、SpringBoot简介
- SpringBoot学习记录1------启动
- Springboot学习记录4------profile
- SpringBoot学习记录5------logback
- SpringBoot 学习记录(二): mybaits
- SpringBoot 学习记录(三): jpa
- SpringBoot 学习记录(六): Exception
- SpringBoot 学习记录(九): Email
- SpringBoot 学习记录(十): scheduler
- springBoot 学习记录(一)
- TMS320F28035学习记录七
- SpringBoot 学习记录(五): aop记录日志
- VS2013配置Qt5.8.0环境
- Paragon NTFS For Mac的破解版究竟有何危害
- oracle forall关键字进行批量操作
- protobuf——VC&pb开发(另附vs2017完整工程及vs可编译pb源码)
- javascript遮罩层编写
- SpringBoot 学习记录(七): Redis
- 项目经理面试的一些建议:
- Css 表单
- VUE2.0 速记
- js晋级篇——前端内存泄漏探讨
- angular最佳实践
- javascript Date时间操作
- HibernateDao层增删改查
- Activiti自我总结