Spring Boot with Redis
Spring Boot是为了简化Spring开发而生,从Spring 3.x开始,Spring社区的发展方向就是弱化xml配置文件而加大注解的戏份。最近召开的SpringOne2GX2015大会上显示:Spring Boot已经是Spring社区中增长最迅速的框架,前三名是:Spring Framework,Spring Boot和Spring Security,这个应该是未来的趋势。
我学习Spring Boot,是因为通过cli工具,spring boot开始往flask(python)、express(nodejs)等web框架发展和靠近,并且Spring Boot几乎不需要写xml配置文件。感兴趣的同学可以根据spring boot quick start这篇文章中的例子尝试下。
学习新的技术最佳途径是看官方文档,现在Spring boot的release版本是1.3.0-RELEASE,相应的参考文档是Spring Boot Reference Guide(1.3.0-REALEASE),如果有绝对英文比较吃力的同学,可以参考中文版Spring Boot参考指南。在前段时间阅读一篇技术文章,介绍如何阅读ios技术文档,我从中也有所收获,那就是我们应该重视spring.io上的guides部分——Getting Started Guides,这部分都是一些针对特定问题的demo,值得学习。
Spring Boot的项目结构com +- example +- myproject +- Application.java +- domain | +- Customer.java | +- CustomerRepository.java +- service | +- CustomerService.java +- web +- CustomerController.java
如上所示,Spring boot项目的结构划分为web- service- domain,其中domain文件夹可类比与业务模型和数据存储,即xxxBean和Dao层;service层是业务逻辑层,web是控制器。比较特别的是,这种类型的项目有自己的入口,即主类,一般命名为Application.java。Application.java不仅提供入口功能,还提供一些底层服务,例如缓存、项目配置等等。
本文的例子是取自我的side project之中,日报(report)的查询,试图利用Redis作为缓存,优化查询效率。
知识点解析 1. 自定义配置Spring Boot允许外化配置,这样你可以在不同的环境下使用相同的代码。你可以使用properties文件、yaml文件,环境变量和命令行参数来外化配置。使用@Value注解,可以直接将属性值注入到你的beans中。
Spring Boot使用一个非常特别的PropertySource来允许对值进行合理的覆盖,按照优先考虑的顺序排位如下:
1. 命令行参数 2. 来自java:comp/env的JNDI属性 3. Java系统属性(System.getProperties()) 4. 操作系统环境变量 5. 只有在random.*里包含的属性会产生一个RandomValuePropertySource 6. 在打包的jar外的应用程序配置文件(application.properties,包含YAML和profile变量) 7. 在打包的jar内的应用程序配置文件(application.properties,包含YAML和profile变量) 8. 在@Configuration类上的@PropertySource注解 9. 默认属性(使用SpringApplication.setDefaultProperties指定)
使用场景:可以将一个application.properties打包在Jar内,用来提供一个合理的默认name值;当运行在生产环境时,可以在Jar外提供一个application.properties文件来覆盖name属性;对于一次性的测试,可以使用特病的命令行开关启动,而不需要重复打包jar包。
具体的例子操作过程如下:
新建配置文件(application.properties)spring.redis.database=0 spring.redis.host=localhost spring.redis.password= # Login password of the redis server. spring.redis.pool.max-active=8 spring.redis.pool.max-idle=8 spring.redis.pool.max-wait=-1 spring.redis.pool.min-idle=0 spring.redis.port=6379 spring.redis.sentinel.master= # Name of Redis server. spring.redis.sentinel.nodes= # Comma-separated list of host:port pairs. spring.redis.timeout=0使用@PropertySource引入配置文件
@Configuration @PropertySource(value = "classpath:/redis.properties") @EnableCaching public class CacheConfig extends CachingConfigurerSupport { ...... }使用@Value引用属性值
@Configuration @PropertySource(value = "classpath:/redis.properties") @EnableCaching public class CacheConfig extends CachingConfigurerSupport { @Value("${spring.redis.host}") private String host; @Value("${spring.redis.port}") private int port; @Value("${spring.redis.timeout}") private int timeout; ...... }
groupId org.springframework.boot /groupId artifactId spring-boot-starter-redis /artifactId /dependency 编写CacheConfig
@Configuration @PropertySource(value = "classpath:/redis.properties") @EnableCaching public class CacheConfig extends CachingConfigurerSupport { @Value("${spring.redis.host}") private String host; @Value("${spring.redis.port}") private int port; @Value("${spring.redis.timeout}") private int timeout; @Bean public KeyGenerator wiselyKeyGenerator(){ 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(); @Bean public JedisConnectionFactory redisConnectionFactory() { JedisConnectionFactory factory = new JedisConnectionFactory(); factory.setHostName(host); factory.setPort(port); factory.setTimeout(timeout); //设置连接超时时间 return factory; @Bean public CacheManager cacheManager(RedisTemplate redisTemplate) { RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); // Number of seconds before expiration. Defaults to unlimited (0) cacheManager.setDefaultExpiration(10); //设置key-value超时时间 return cacheManager; @Bean public RedisTemplate String, String redisTemplate(RedisConnectionFactory factory) { StringRedisTemplate template = new StringRedisTemplate(factory); setSerializer(template); //设置序列化工具,这样ReportBean不需要实现Serializable接口 template.afterPropertiesSet(); return template; private void setSerializer(StringRedisTemplate template) { Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); template.setValueSerializer(jackson2JsonRedisSerializer); }启动缓存,使用@Cacheable注解在需要缓存的接口上即可
@Service public class ReportService { @Cacheable(value = "reportcache", keyGenerator = "wiselyKeyGenerator") public ReportBean getReport(Long id, String date, String content, String title) { System.out.println("无缓存的时候调用这里---数据库查询"); return new ReportBean(id, date, content, title); }运行方法如下: mvn clean package java -jar target/dailyReport-1.0-SNAPSHOT.jar
Spring boot 使用 ON DUPLICATE KEY UPDATE属性控制版本 更新数据不成功 如果更新不成功会报下面的错误(此错误是自定义的): The data you want to update has been updated by another user. Please reopen and try again! 一、主要按下面的流程检查: 1、检查数据库的段alastupdatetime定义 2、检查.xml的alastupdatetime 3、要更新数据的主键是否在同一个updateByBatch中的List中重复出现
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载
相关文章
- Spring配置cache(concurrentHashMap,guava cache、redis实现)附源码
- Redis 生产架构选型对比,一文整治选择困难症
- spring boot:用redis+lua限制短信验证码的发送频率(spring boot 2.3.2)
- spring boot:redis+lua实现生产环境中可用的秒杀功能(spring boot 2.2.0)
- spring boot:用redis+lua实现基于ip地址的分布式流量限制(限流/简单计数器算法)(spring boot 2.2.0)
- spring boot下JedisCluster方式连接Redis集群的配置
- 深入理解Spring Redis的使用 (六)、用Spring Aop 实现注解Dao层的自动Spring Redis缓存
- spring boot:在服务端用redis存储jwt登录后的用户信息(spring boot 2.4.4)
- spring boot: 用redis的消息订阅功能更新应用内的caffeine本地缓存(spring boot 2.3.2)
- spring boot:redis+lua实现顺序自增的唯一id发号器(spring boot 2.3.1)
- spring boot:用redis+lua实现基于ip地址的分布式流量限制(限流/简单计数器算法)(spring boot 2.2.0)
- spring-boot 中实现标准 redis 分布式锁
- redis在spring中的配置及java代码实现
- 毕设/私活/bigold必备项目,一个挣钱的免费的全开源标准前后端分离后台管理权限系统【springboot+vue+redis+Spring Security】脚手架搭建:若依Ruo框架具体使用教程
- 【SpringBoot系列】Spring Boot+Redis 分布式锁:模拟抢单
- 【架构师修炼之路】Redis 极简教程 : 基本数据结构, 跳表原理, Spring Boot 项目使用实例
- 【Spring Boot】Spring Boot以Repository方式整合Redis