Skip to content

Commit bb038a2

Browse files
committed
Create spring-boot-with-redis.md
1 parent b78e449 commit bb038a2

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed

spring-boot-with-redis.md

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
## Spring Boot简介
2+
Spring Boot是为了简化Spring开发而生,从Spring 3.x开始,Spring社区的发展方向就是弱化xml配置文件而加大注解的戏份。最近召开的SpringOne2GX2015大会上显示:Spring Boot已经是Spring社区中增长最迅速的框架,前三名是:Spring Framework,Spring Boot和Spring Security,这个应该是未来的趋势。
3+
4+
我学习Spring Boot,是因为通过cli工具,spring boot开始往flask(python)、express(nodejs)等web框架发展和靠近,并且Spring Boot几乎不需要写xml配置文件。感兴趣的同学可以根据[spring boot quick start](http://projects.spring.io/spring-boot/#quick-start)这篇文章中的例子尝试下。
5+
6+
学习新的技术最佳途径是看官方文档,现在Spring boot的release版本是1.3.0-RELEASE,相应的参考文档是[Spring Boot Reference Guide(1.3.0-REALEASE)](http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/),如果有绝对英文比较吃力的同学,可以参考中文版[Spring Boot参考指南](https://www.gitbook.com/book/qbgbook/spring-boot-reference-guide-zh/details)。在前段时间阅读一篇技术文章,介绍如何阅读ios技术文档,我从中也有所收获,那就是我们应该重视spring.io上的guides部分——[Getting Started Guides](http://spring.io/guides),这部分都是一些针对特定问题的demo,值得学习。
7+
8+
## Spring Boot的项目结构
9+
```
10+
com
11+
+- example
12+
+- myproject
13+
+- Application.java
14+
|
15+
+- domain
16+
| +- Customer.java
17+
| +- CustomerRepository.java
18+
|
19+
+- service
20+
| +- CustomerService.java
21+
|
22+
+- web
23+
+- CustomerController.java
24+
```
25+
如上所示,Spring boot项目的结构划分为web->service->domain,其中domain文件夹可类比与业务模型和数据存储,即xxxBean和Dao层;service层是业务逻辑层,web是控制器。比较特别的是,这种类型的项目有自己的入口,即主类,一般命名为Application.java。Application.java不仅提供入口功能,还提供一些底层服务,例如缓存、项目配置等等。
26+
27+
## 例子介绍
28+
本文的例子是取自我的side project之中,日报(report)的查询,试图利用Redis作为缓存,优化查询效率。
29+
30+
## 知识点解析
31+
### 1. 自定义配置
32+
Spring Boot允许外化配置,这样你可以在不同的环境下使用相同的代码。你可以使用properties文件、yaml文件,环境变量和命令行参数来外化配置。使用@Value注解,可以直接将属性值注入到你的beans中。
33+
Spring Boot使用一个非常特别的PropertySource来允许对值进行合理的覆盖,按照优先考虑的顺序排位如下:
34+
```
35+
1. 命令行参数
36+
2. 来自java:comp/env的JNDI属性
37+
3. Java系统属性(System.getProperties())
38+
4. 操作系统环境变量
39+
5. 只有在random.*里包含的属性会产生一个RandomValuePropertySource
40+
6. 在打包的jar外的应用程序配置文件(application.properties,包含YAML和profile变量)
41+
7. 在打包的jar内的应用程序配置文件(application.properties,包含YAML和profile变量)
42+
8. 在@Configuration类上的@PropertySource注解
43+
9. 默认属性(使用SpringApplication.setDefaultProperties指定)
44+
```
45+
**使用场景**:可以将一个application.properties打包在Jar内,用来提供一个合理的默认name值;当运行在生产环境时,可以在Jar外提供一个application.properties文件来覆盖name属性;对于一次性的测试,可以使用特病的命令行开关启动,而不需要重复打包jar包。
46+
47+
具体的例子操作过程如下:
48+
49+
- 新建配置文件(application.properties)
50+
```
51+
spring.redis.database=0
52+
spring.redis.host=localhost
53+
spring.redis.password= # Login password of the redis server.
54+
spring.redis.pool.max-active=8
55+
spring.redis.pool.max-idle=8
56+
spring.redis.pool.max-wait=-1
57+
spring.redis.pool.min-idle=0
58+
spring.redis.port=6379
59+
spring.redis.sentinel.master= # Name of Redis server.
60+
spring.redis.sentinel.nodes= # Comma-separated list of host:port pairs.
61+
spring.redis.timeout=0
62+
```
63+
- 使用@PropertySource引入配置文件
64+
65+
```
66+
@Configuration
67+
@PropertySource(value = "classpath:/redis.properties")
68+
@EnableCaching
69+
public class CacheConfig extends CachingConfigurerSupport {
70+
......
71+
}
72+
```
73+
- 使用@Value引用属性值
74+
75+
```
76+
@Configuration
77+
@PropertySource(value = "classpath:/redis.properties")
78+
@EnableCaching
79+
public class CacheConfig extends CachingConfigurerSupport {
80+
@Value("${spring.redis.host}")
81+
private String host;
82+
@Value("${spring.redis.port}")
83+
private int port;
84+
@Value("${spring.redis.timeout}")
85+
private int timeout;
86+
......
87+
}
88+
```
89+
90+
91+
### 2. redis使用
92+
- 添加pom配置
93+
94+
```
95+
<dependency>
96+
<groupId>org.springframework.boot</groupId>
97+
<artifactId>spring-boot-starter-redis</artifactId>
98+
</dependency>
99+
```
100+
- 编写CacheConfig
101+
102+
```
103+
@Configuration
104+
@PropertySource(value = "classpath:/redis.properties")
105+
@EnableCaching
106+
public class CacheConfig extends CachingConfigurerSupport {
107+
@Value("${spring.redis.host}")
108+
private String host;
109+
@Value("${spring.redis.port}")
110+
private int port;
111+
@Value("${spring.redis.timeout}")
112+
private int timeout;
113+
@Bean
114+
public KeyGenerator wiselyKeyGenerator(){
115+
return new KeyGenerator() {
116+
@Override
117+
public Object generate(Object target, Method method, Object... params) {
118+
StringBuilder sb = new StringBuilder();
119+
sb.append(target.getClass().getName());
120+
sb.append(method.getName());
121+
for (Object obj : params) {
122+
sb.append(obj.toString());
123+
}
124+
return sb.toString();
125+
}
126+
};
127+
}
128+
@Bean
129+
public JedisConnectionFactory redisConnectionFactory() {
130+
JedisConnectionFactory factory = new JedisConnectionFactory();
131+
factory.setHostName(host);
132+
factory.setPort(port);
133+
factory.setTimeout(timeout); //设置连接超时时间
134+
return factory;
135+
}
136+
@Bean
137+
public CacheManager cacheManager(RedisTemplate redisTemplate) {
138+
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
139+
// Number of seconds before expiration. Defaults to unlimited (0)
140+
cacheManager.setDefaultExpiration(10); //设置key-value超时时间
141+
return cacheManager;
142+
}
143+
@Bean
144+
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
145+
StringRedisTemplate template = new StringRedisTemplate(factory);
146+
setSerializer(template); //设置序列化工具,这样ReportBean不需要实现Serializable接口
147+
template.afterPropertiesSet();
148+
return template;
149+
}
150+
private void setSerializer(StringRedisTemplate template) {
151+
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
152+
ObjectMapper om = new ObjectMapper();
153+
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
154+
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
155+
jackson2JsonRedisSerializer.setObjectMapper(om);
156+
template.setValueSerializer(jackson2JsonRedisSerializer);
157+
}
158+
}
159+
```
160+
- 启动缓存,使用@Cacheable注解在需要缓存的接口上即可
161+
162+
```
163+
@Service
164+
public class ReportService {
165+
@Cacheable(value = "reportcache", keyGenerator = "wiselyKeyGenerator")
166+
public ReportBean getReport(Long id, String date, String content, String title) {
167+
System.out.println("无缓存的时候调用这里---数据库查询");
168+
return new ReportBean(id, date, content, title);
169+
}
170+
}
171+
```
172+
- 测试验证
173+
- 运行方法如下:
174+
- mvn clean package
175+
- java -jar target/dailyReport-1.0-SNAPSHOT.jar
176+
- 验证缓存起作用:
177+
- 访问:http://localhost:8080/report/test
178+
- 访问:http://localhost:8080/report/test2
179+
- 验证缓存失效(10s+后执行):
180+
- 访问:http://localhost:8080/report/test2
181+
182+
##参考资料
183+
1. [spring boot quick start](http://projects.spring.io/spring-boot/#quick-start)
184+
2. [Spring Boot参考指南](https://www.gitbook.com/book/qbgbook/spring-boot-reference-guide-zh/details)
185+
3. [Spring Boot Reference Guide(1.3.0-REALEASE)](http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/)
186+
4. [Getting Started Guides](http://spring.io/guides)
187+
5. [Caching Data in Spring Using Redis](http://caseyscarborough.com/blog/2014/12/18/caching-data-in-spring-using-redis/)
188+
6. [Spring boot使用Redis做缓存](http://wiselyman.iteye.com/blog/2184884)
189+
7. [redis设计与实现](http://redisbook.com/index.html)

0 commit comments

Comments
 (0)