@@ -1,6 +1,6 @@ | |||
# Spring Boot Demo | |||
spring boot demo 一个用来学习 spring boot 的项目,已经集成 actuator、logback、mybatis 模块,后续会集成activemq,redis,email, freemarker,shiro,websocket,sitemesh,ehcache,easyui,kindeditor,quartz,springfox,swagger,jpa,hibernate,querydsl,netty等模块。 | |||
spring boot demo 一个用来学习 spring boot 的项目,已经集成 actuator、logback、jpa、mybatis、redis缓存 模块,后续会集成activemq,email, freemarker,shiro,websocket,quartz,springfox,swagger,netty等模块。 | |||
依赖的 Spring Boot 版本: | |||
@@ -40,6 +40,7 @@ spring boot demo 一个用来学习 spring boot 的项目,已经集成 actuato | |||
<module>../spring-boot-demo-logback</module> | |||
<module>../spring-boot-demo-jpa</module> | |||
<module>../spring-boot-demo-mybatis</module> | |||
<module>../spring-boot-demo-cache-redis</module> | |||
</modules> | |||
<parent> | |||
@@ -53,6 +54,10 @@ spring boot demo 一个用来学习 spring boot 的项目,已经集成 actuato | |||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||
<java.version>1.8</java.version> | |||
<hutool.version>3.2.0</hutool.version> | |||
<commons.lang3.version>3.5</commons.lang3.version> | |||
<commons.collections.version>3.2.2</commons.collections.version> | |||
<commons.codec.version>1.10</commons.codec.version> | |||
</properties> | |||
<dependencies> | |||
@@ -76,9 +81,24 @@ spring boot demo 一个用来学习 spring boot 的项目,已经集成 actuato | |||
</dependency> | |||
<!--工具类--> | |||
<dependency> | |||
<groupId>org.apache.commons</groupId> | |||
<artifactId>commons-lang3</artifactId> | |||
<version>${commons.lang3.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>commons-collections</groupId> | |||
<artifactId>commons-collections</artifactId> | |||
<version>${commons.collections.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>commons-codec</groupId> | |||
<artifactId>commons-codec</artifactId> | |||
<version>${commons.codec.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.xiaoleilu</groupId> | |||
<artifactId>hutool-all</artifactId> | |||
<version>3.1.2</version> | |||
<version>${hutool.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.google.guava</groupId> | |||
@@ -113,6 +133,7 @@ spring boot demo 一个用来学习 spring boot 的项目,已经集成 actuato | |||
| [spring-boot-demo-logback](./spring-boot-demo-logback) | spring-boot 集成 logback 日志 | | |||
| [spring-boot-demo-jpa](./spring-boot-demo-jpa) | spring-boot 集成 spring-boot-starter-data-jpa 操作数据库 | | |||
| [spring-boot-demo-mybatis](./spring-boot-demo-mybatis) | spring-boot 集成 [mybatis-spring-boot-starter](https://github.com/mybatis/spring-boot-starter)、[mybatis-spring-boot-starter](https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter) | | |||
| [spring-boot-demo-cache-redis](./spring-boot-demo-cache-redis) | spring-boot 使用 Redis 做缓存 | | |||
# 官方提供的 starter 介绍 | |||
@@ -0,0 +1,172 @@ | |||
# spring-boot-demo-cache-redis | |||
依赖 [spring-boot-demo-parent](../spring-boot-demo-parent)、`spring-boot-starter-data-redis` | |||
### pom.xml | |||
```xml | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
<modelVersion>4.0.0</modelVersion> | |||
<artifactId>spring-boot-demo-cache-redis</artifactId> | |||
<version>0.0.1-SNAPSHOT</version> | |||
<packaging>war</packaging> | |||
<name>spring-boot-demo-cache-redis</name> | |||
<description>Demo project for Spring Boot</description> | |||
<parent> | |||
<groupId>com.xkcoding</groupId> | |||
<artifactId>spring-boot-demo-parent</artifactId> | |||
<version>0.0.1-SNAPSHOT</version> | |||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||
</parent> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-data-redis</artifactId> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
<finalName>spring-boot-demo-cache-redis</finalName> | |||
</build> | |||
</project> | |||
``` | |||
### application.yml | |||
```yml | |||
server: | |||
port: 8080 | |||
context-path: /demo | |||
spring: | |||
redis: | |||
host: localhost | |||
port: 6379 | |||
``` | |||
### SpringBootDemoCacheRedisApplication.java (开启使用缓存注解) | |||
```java | |||
@SpringBootApplication | |||
@EnableCaching | |||
public class SpringBootDemoCacheRedisApplication { | |||
public static void main(String[] args) { | |||
SpringApplication.run(SpringBootDemoCacheRedisApplication.class, args); | |||
} | |||
} | |||
``` | |||
### User.java (一定要序列化!) | |||
```java | |||
@Data | |||
public class User implements Serializable { | |||
private static final long serialVersionUID = 1442134563392432775L; | |||
private Long id; | |||
private String name; | |||
private Date birthDay; | |||
} | |||
``` | |||
### UserController.java | |||
```java | |||
@RestController | |||
@RequestMapping("/user") | |||
@CacheConfig(cacheNames = "users") // 整体配置缓存的名称 | |||
public class UserController { | |||
@Autowired | |||
private UserService userService; | |||
@GetMapping({"", "/"}) | |||
@Cacheable | |||
public List<User> index() { | |||
return userService.find(); | |||
} | |||
@GetMapping("/find/{id}") | |||
@Cacheable(key = "#id", condition = "#id != null") // #id 以及 condition 里的语法是 SpEL 语法 | |||
public User find(@PathVariable Long id) { | |||
return userService.find(id); | |||
} | |||
@GetMapping("/find") | |||
@Cacheable(key = "#name", condition = "#name != null") | |||
public User find(@RequestParam String name) { | |||
return userService.find(name); | |||
} | |||
@GetMapping("/save") | |||
@CacheEvict(allEntries = true, beforeInvocation = true) //@CacheEvict 清空缓存 | |||
public User save() { | |||
return userService.save(); | |||
} | |||
@GetMapping("/update/{id}") | |||
@CacheEvict(allEntries = true, beforeInvocation = true) | |||
public User update(@PathVariable Long id) { | |||
return userService.update(id); | |||
} | |||
@GetMapping("/delete/{id}") | |||
@CacheEvict(allEntries = true, beforeInvocation = true) | |||
public String delete(@PathVariable Long id) { | |||
User user = userService.delete(id); | |||
if (user == null) { | |||
return "用户不存在"; | |||
} else { | |||
return user.getName() + "删除成功"; | |||
} | |||
} | |||
} | |||
``` | |||
### 其余 Service、Dao 代码(采用 List 存储,只为了演示启用 cache 后,是否仍会进入对应的 method) | |||
详情请参见本demo。 | |||
### 缓存 @Annotation 详解 | |||
#### @CacheConfig | |||
用于统一配置缓存的基本信息 | |||
#### @Cacheable | |||
将返回的结果缓存,该注解里的参数如下 | |||
| 参数 | 作用 | 示例 | | |||
| --------- | ---------------------------------------- | ---------------------------------------- | | |||
| value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如:@Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”} | | |||
| key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如:@Cacheable(value=”testcache”,key=”#userName”) | | |||
| condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 | 例如:@Cacheable(value=”testcache”,condition=”#userName.length()>2”) | | |||
#### @CacheEvict | |||
能够根据一定的条件对缓存进行清空,该注解里的参数如下 | |||
| 参数 | 作用 | 示例 | | |||
| ---------------- | ---------------------------------------- | ---------------------------------------- | | |||
| value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如:@CachEvict(value=”mycache”) 或者 @CachEvict(value={”cache1”,”cache2”} | | |||
| key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如:@CachEvict(value=”testcache”,key=”#userName”) | | |||
| condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存 | 例如:@CachEvict(value=”testcache”,condition=”#userName.length()>2”) | | |||
| allEntries | 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 | 例如:@CachEvict(value=”testcache”,allEntries=true) | | |||
| beforeInvocation | 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 | 例如:@CachEvict(value=”testcache”,beforeInvocation=true) | | |||
#### @CachePut | |||
能够根据方法的请求参数对其结果进行缓存,和 `@Cacheable` 不同的是,它每次都会触发真实方法的调用 | |||
| 参数 | 作用 | 示例 | | |||
| --------- | ---------------------------------------- | ---------------------------------------- | | |||
| value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如:@Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”} | | |||
| key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如:@Cacheable(value=”testcache”,key=”#userName”) | | |||
| condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 | 例如:@Cacheable(value=”testcache”,condition=”#userName.length()>2”) | |
@@ -0,0 +1,31 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
<modelVersion>4.0.0</modelVersion> | |||
<artifactId>spring-boot-demo-cache-redis</artifactId> | |||
<version>0.0.1-SNAPSHOT</version> | |||
<packaging>war</packaging> | |||
<name>spring-boot-demo-cache-redis</name> | |||
<description>Demo project for Spring Boot</description> | |||
<parent> | |||
<groupId>com.xkcoding</groupId> | |||
<artifactId>spring-boot-demo-parent</artifactId> | |||
<version>0.0.1-SNAPSHOT</version> | |||
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath> | |||
</parent> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-data-redis</artifactId> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
<finalName>spring-boot-demo-cache-redis</finalName> | |||
</build> | |||
</project> |
@@ -0,0 +1,14 @@ | |||
package com.xkcoding.springbootdemocacheredis; | |||
import org.springframework.boot.SpringApplication; | |||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||
import org.springframework.cache.annotation.EnableCaching; | |||
@SpringBootApplication | |||
@EnableCaching | |||
public class SpringBootDemoCacheRedisApplication { | |||
public static void main(String[] args) { | |||
SpringApplication.run(SpringBootDemoCacheRedisApplication.class, args); | |||
} | |||
} |
@@ -0,0 +1,61 @@ | |||
package com.xkcoding.springbootdemocacheredis.controller; | |||
import com.xkcoding.springbootdemocacheredis.entity.User; | |||
import com.xkcoding.springbootdemocacheredis.service.UserService; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.cache.annotation.CacheConfig; | |||
import org.springframework.cache.annotation.CacheEvict; | |||
import org.springframework.cache.annotation.Cacheable; | |||
import org.springframework.web.bind.annotation.*; | |||
import java.util.List; | |||
@RestController | |||
@RequestMapping("/user") | |||
@CacheConfig(cacheNames = "users") // 整体配置缓存的名称 | |||
public class UserController { | |||
@Autowired | |||
private UserService userService; | |||
@GetMapping({"", "/"}) | |||
@Cacheable | |||
public List<User> index() { | |||
return userService.find(); | |||
} | |||
@GetMapping("/find/{id}") | |||
@Cacheable(key = "#id", condition = "#id != null") // #id 以及 condition 里的语法是 SpEL 语法 | |||
public User find(@PathVariable Long id) { | |||
return userService.find(id); | |||
} | |||
@GetMapping("/find") | |||
@Cacheable(key = "#name", condition = "#name != null") | |||
public User find(@RequestParam String name) { | |||
return userService.find(name); | |||
} | |||
@GetMapping("/save") | |||
@CacheEvict(allEntries = true, beforeInvocation = true) //@CacheEvict 清空缓存 | |||
public User save() { | |||
return userService.save(); | |||
} | |||
@GetMapping("/update/{id}") | |||
@CacheEvict(allEntries = true, beforeInvocation = true) | |||
public User update(@PathVariable Long id) { | |||
return userService.update(id); | |||
} | |||
@GetMapping("/delete/{id}") | |||
@CacheEvict(allEntries = true, beforeInvocation = true) | |||
public String delete(@PathVariable Long id) { | |||
User user = userService.delete(id); | |||
if (user == null) { | |||
return "用户不存在"; | |||
} else { | |||
return user.getName() + "删除成功"; | |||
} | |||
} | |||
} |
@@ -0,0 +1,71 @@ | |||
package com.xkcoding.springbootdemocacheredis.dao; | |||
import com.google.common.collect.Lists; | |||
import com.xkcoding.springbootdemocacheredis.entity.User; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Date; | |||
import java.util.List; | |||
import java.util.concurrent.atomic.AtomicLong; | |||
@Slf4j | |||
@Component | |||
public class UserDao { | |||
private static List<User> users = Lists.newArrayList(); | |||
private static AtomicLong SEQ = new AtomicLong(0L); | |||
public User save() { | |||
log.info("save....."); | |||
User user = new User(); | |||
user.setId(SEQ.get()); | |||
user.setName("xkcoding" + SEQ.get()); | |||
user.setBirthDay(new Date()); | |||
users.add(user); | |||
SEQ.getAndIncrement(); | |||
return user; | |||
} | |||
public User update(Long id) { | |||
log.info("update....."); | |||
for (User user1 : users) { | |||
if (user1.getId().equals(id)) { | |||
user1.setName("修改后的名字"); | |||
return user1; | |||
} | |||
} | |||
return null; | |||
} | |||
public User delete(Long id) { | |||
log.info("delete....."); | |||
User user = find(id); | |||
users.remove(user); | |||
return user; | |||
} | |||
public List<User> find() { | |||
log.info("findAll....."); | |||
return users; | |||
} | |||
public User find(String name) { | |||
log.info("findByName....."); | |||
for (User user : users) { | |||
if (user.getName().equals(name)) { | |||
return user; | |||
} | |||
} | |||
return null; | |||
} | |||
public User find(Long id) { | |||
log.info("findById....."); | |||
for (User user : users) { | |||
if (user.getId().equals(id)) { | |||
return user; | |||
} | |||
} | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,14 @@ | |||
package com.xkcoding.springbootdemocacheredis.entity; | |||
import lombok.Data; | |||
import java.io.Serializable; | |||
import java.util.Date; | |||
@Data | |||
public class User implements Serializable { | |||
private static final long serialVersionUID = 1442134563392432775L; | |||
private Long id; | |||
private String name; | |||
private Date birthDay; | |||
} |
@@ -0,0 +1,19 @@ | |||
package com.xkcoding.springbootdemocacheredis.service; | |||
import com.xkcoding.springbootdemocacheredis.entity.User; | |||
import java.util.List; | |||
public interface UserService { | |||
User save(); | |||
User update(Long id); | |||
User delete(Long id); | |||
List<User> find(); | |||
User find(Long id); | |||
User find(String name); | |||
} |
@@ -0,0 +1,47 @@ | |||
package com.xkcoding.springbootdemocacheredis.service.impl; | |||
import com.xkcoding.springbootdemocacheredis.dao.UserDao; | |||
import com.xkcoding.springbootdemocacheredis.entity.User; | |||
import com.xkcoding.springbootdemocacheredis.service.UserService; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.cache.annotation.CacheConfig; | |||
import org.springframework.cache.annotation.CachePut; | |||
import org.springframework.stereotype.Service; | |||
import java.util.List; | |||
@Service | |||
public class UserServiceImpl implements UserService { | |||
@Autowired | |||
private UserDao userDao; | |||
@Override | |||
public User save() { | |||
return userDao.save(); | |||
} | |||
@Override | |||
public User update(Long id) { | |||
return userDao.update(id); | |||
} | |||
@Override | |||
public User delete(Long id) { | |||
return userDao.delete(id); | |||
} | |||
@Override | |||
public List<User> find() { | |||
return userDao.find(); | |||
} | |||
@Override | |||
public User find(Long id) { | |||
return userDao.find(id); | |||
} | |||
@Override | |||
public User find(String name) { | |||
return userDao.find(name); | |||
} | |||
} |
@@ -0,0 +1,7 @@ | |||
server: | |||
port: 8080 | |||
context-path: /demo | |||
spring: | |||
redis: | |||
host: localhost | |||
port: 6379 |
@@ -0,0 +1,16 @@ | |||
package com.xkcoding.springbootdemocacheredis; | |||
import org.junit.Test; | |||
import org.junit.runner.RunWith; | |||
import org.springframework.boot.test.context.SpringBootTest; | |||
import org.springframework.test.context.junit4.SpringRunner; | |||
@RunWith(SpringRunner.class) | |||
@SpringBootTest | |||
public class SpringBootDemoCacheRedisApplicationTests { | |||
@Test | |||
public void contextLoads() { | |||
} | |||
} |
@@ -18,6 +18,7 @@ | |||
<module>../spring-boot-demo-logback</module> | |||
<module>../spring-boot-demo-jpa</module> | |||
<module>../spring-boot-demo-mybatis</module> | |||
<module>../spring-boot-demo-cache-redis</module> | |||
</modules> | |||
<parent> | |||