├── README.md
├── src
├── main
│ ├── resources
│ │ └── application.properties
│ └── java
│ │ └── com
│ │ └── example
│ │ ├── exceptions
│ │ └── PostNotFoundException.java
│ │ ├── model
│ │ ├── Author.java
│ │ └── Post.java
│ │ ├── RedisCacheApplication.java
│ │ ├── controllers
│ │ ├── PostExceptionHandler.java
│ │ └── PostController.java
│ │ └── services
│ │ └── PostService.java
└── test
│ └── java
│ └── com
│ └── example
│ └── DemoApplicationTests.java
├── .mvn
└── wrapper
│ └── maven-wrapper.properties
├── .gitignore
└── pom.xml
/README.md:
--------------------------------------------------------------------------------
1 | # spring-boot-redis-cache
--------------------------------------------------------------------------------
/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.cache.type=redis
2 | spring.redis.host=192.168.99.100
3 | spring.redis.port=6379
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
2 |
--------------------------------------------------------------------------------
/src/main/java/com/example/exceptions/PostNotFoundException.java:
--------------------------------------------------------------------------------
1 | package com.example.exceptions;
2 |
3 | public class PostNotFoundException extends Exception {
4 | public PostNotFoundException(String message) {
5 | super(message);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
3 | # Mobile Tools for Java (J2ME)
4 | .mtj.tmp/
5 |
6 | # Package Files #
7 | *.jar
8 | *.war
9 | *.ear
10 |
11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
12 | hs_err_pid*
13 | .idea/
14 | *.iml
15 | target/
16 | mvnw.cmd
17 | mvnw
18 |
--------------------------------------------------------------------------------
/src/test/java/com/example/DemoApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class DemoApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/example/model/Author.java:
--------------------------------------------------------------------------------
1 | package com.example.model;
2 |
3 | import java.io.Serializable;
4 |
5 | public class Author implements Serializable {
6 |
7 | private String name;
8 |
9 | public Author() {
10 | }
11 |
12 | public Author(String name) {
13 | this.name = name;
14 | }
15 |
16 | public String getName() {
17 | return name;
18 | }
19 |
20 | public void setName(String name) {
21 | this.name = name;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/example/RedisCacheApplication.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cache.annotation.EnableCaching;
6 | import org.springframework.scheduling.annotation.EnableScheduling;
7 |
8 | @EnableCaching
9 | @SpringBootApplication
10 | public class RedisCacheApplication {
11 | public static void main(String[] args) {
12 | SpringApplication.run(RedisCacheApplication.class, args);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/example/controllers/PostExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package com.example.controllers;
2 |
3 | import com.example.exceptions.PostNotFoundException;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.springframework.http.HttpStatus;
7 | import org.springframework.web.bind.annotation.ControllerAdvice;
8 | import org.springframework.web.bind.annotation.ExceptionHandler;
9 | import org.springframework.web.bind.annotation.ResponseStatus;
10 |
11 | import javax.servlet.http.HttpServletRequest;
12 |
13 | @ControllerAdvice
14 | public class PostExceptionHandler {
15 |
16 | private Logger log = LoggerFactory.getLogger(PostExceptionHandler.class);
17 |
18 | @ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Post Not Found")
19 | @ExceptionHandler(PostNotFoundException.class)
20 | public void handlePostNotFound(HttpServletRequest request, Exception ex) {
21 | log.error("{} : {}", ex.getMessage(), request.getRequestURI());
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/example/model/Post.java:
--------------------------------------------------------------------------------
1 | package com.example.model;
2 |
3 | import java.io.Serializable;
4 |
5 | public class Post implements Serializable {
6 |
7 | private String id;
8 | private String title;
9 | private String description;
10 | private String image;
11 | private int shares;
12 | private Author author;
13 |
14 | public Post() {
15 | }
16 |
17 | public Post(String id, String title, String description, String image, int shares, Author author) {
18 | this.id = id;
19 | this.title = title;
20 | this.description = description;
21 | this.image = image;
22 | this.shares = shares;
23 | this.author = author;
24 | }
25 |
26 | public String getId() {
27 | return id;
28 | }
29 |
30 | public void setId(String id) {
31 | this.id = id;
32 | }
33 |
34 | public String getTitle() {
35 | return title;
36 | }
37 |
38 | public void setTitle(String title) {
39 | this.title = title;
40 | }
41 |
42 | public String getDescription() {
43 | return description;
44 | }
45 |
46 | public void setDescription(String description) {
47 | this.description = description;
48 | }
49 |
50 | public String getImage() {
51 | return image;
52 | }
53 |
54 | public void setImage(String image) {
55 | this.image = image;
56 | }
57 |
58 | public int getShares() {
59 | return shares;
60 | }
61 |
62 | public void setShares(int shares) {
63 | this.shares = shares;
64 | }
65 |
66 | public Author getAuthor() {
67 | return author;
68 | }
69 |
70 | public void setAuthor(Author author) {
71 | this.author = author;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | spring-with-redis-cache
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | Spring cache
12 | Spring Boot with Redis cache
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 1.5.2.RELEASE
18 |
19 |
20 |
21 | UTF-8
22 | UTF-8
23 | 1.8
24 |
25 |
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter-web
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-devtools
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-starter-data-redis
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-starter-test
42 | test
43 |
44 |
45 |
46 |
47 |
48 |
49 | org.springframework.boot
50 | spring-boot-maven-plugin
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/main/java/com/example/controllers/PostController.java:
--------------------------------------------------------------------------------
1 | package com.example.controllers;
2 |
3 | import com.example.exceptions.PostNotFoundException;
4 | import com.example.model.Post;
5 | import com.example.services.PostService;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.cache.annotation.CacheEvict;
10 | import org.springframework.cache.annotation.CachePut;
11 | import org.springframework.cache.annotation.Cacheable;
12 | import org.springframework.web.bind.annotation.*;
13 |
14 | import java.util.List;
15 |
16 | @RestController
17 | @RequestMapping("/posts")
18 | public class PostController {
19 |
20 | private static final Logger log = LoggerFactory.getLogger(PostController.class);
21 |
22 | @Autowired
23 | private PostService postService;
24 |
25 | @Cacheable(value = "post-single", key = "#id", unless = "#result.shares < 500")
26 | @GetMapping("/{id}")
27 | public Post getPostByID(@PathVariable String id) throws PostNotFoundException {
28 | log.info("get post with id {}", id);
29 | return postService.getPostByID(id);
30 | }
31 |
32 | @CachePut(value = "post-single", key = "#post.id")
33 | @PutMapping("/update")
34 | public Post updatePostByID(@RequestBody Post post) throws PostNotFoundException {
35 | log.info("update post with id {}", post.getId());
36 | postService.updatePost(post);
37 | return post;
38 | }
39 |
40 | @CacheEvict(value = "post-single", key = "#id")
41 | @DeleteMapping("/delete/{id}")
42 | public void deletePostByID(@PathVariable String id) throws PostNotFoundException {
43 | log.info("delete post with id {}", id);
44 | postService.deletePost(id);
45 | }
46 |
47 | @Cacheable(value = "post-top")
48 | @GetMapping("/top")
49 | public List getTopPosts() {
50 | return postService.getTopPosts();
51 | }
52 |
53 | @CacheEvict(value = "post-top")
54 | @GetMapping("/top/evict")
55 | public void evictTopPosts() {
56 | log.info("Evict post-top");
57 | }
58 |
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/src/main/java/com/example/services/PostService.java:
--------------------------------------------------------------------------------
1 | package com.example.services;
2 |
3 | import com.example.exceptions.PostNotFoundException;
4 | import com.example.model.Author;
5 | import com.example.model.Post;
6 | import org.springframework.stereotype.Service;
7 |
8 | import javax.annotation.PostConstruct;
9 | import java.util.ArrayList;
10 | import java.util.List;
11 | import java.util.concurrent.TimeUnit;
12 | import java.util.stream.Collectors;
13 |
14 | @Service
15 | public class PostService {
16 |
17 | private List posts;
18 |
19 | @PostConstruct
20 | public void init() {
21 | posts = new ArrayList<>();
22 | posts.add(new Post("IDX001", "Cyberpunk is near", "Description", "https://random-cdn.posts/images/xvn84934fnls.jpg", 555, new Author("Anna")));
23 | posts.add(new Post("IDX002", "Welcome aboard of the hype train", "Description", "https://random-cdn.posts/images/xvn84934fnls.jpg", 55, new Author("Josh")));
24 | posts.add(new Post("IDX003", "How to improve programming skills ", "Description", "https://random-cdn.posts/images/xvn84934fnls.jpg", 555, new Author("Kobe")));
25 | posts.add(new Post("IDX004", "Top exercises for IT people", "Description", "https://random-cdn.posts/images/xvn84934fnls.jpg", 55, new Author("Leo")));
26 | posts.add(new Post("IDX005", "Case study of 75 years project", "Description", "https://random-cdn.posts/images/xvn84934fnls.jpg", 55, new Author("Tom")));
27 | posts.add(new Post("IDX006", "Machine Learning", "Description", "https://random-cdn.posts/images/xvn84934fnls.jpg", 255, new Author("Alexa")));
28 | posts.add(new Post("IDX007", "Memory leaks, how to find them ", "Description", "https://random-cdn.posts/images/xvn84934fnls.jpg", 55, new Author("Frank")));
29 | posts.add(new Post("IDX008", "Robots builds robots", "Description", "https://random-cdn.posts/images/xvn84934fnls.jpg", 155, new Author("Milagros")));
30 | posts.add(new Post("IDX009", "Quantum algorithms, from the scratch", "Description", "https://random-cdn.posts/images/xvn84934fnls.jpg", 455, new Author("Sarah")));
31 | posts.add(new Post("IDX010", "Coding, coding, coding", "Description", "https://random-cdn.posts/images/xvn84934fnls.jpg", 255, new Author("Adam")));
32 | }
33 |
34 | public void updatePost(Post post) {
35 | posts = posts.stream().filter(p -> p.getId() != post.getId()).collect(Collectors.toList());
36 | posts.add(post);
37 | }
38 |
39 | public void deletePost(String postID) {
40 | posts = posts.stream().filter(p -> !p.getId().equals(postID)).collect(Collectors.toList());
41 | }
42 |
43 |
44 | /**
45 | * Load post content from DB *Long running method
46 | */
47 | public Post getPostByID(String postID) throws PostNotFoundException {
48 | try {
49 | TimeUnit.SECONDS.sleep(1);
50 | } catch (InterruptedException e) {
51 | e.printStackTrace();
52 | }
53 | return posts.stream()
54 | .filter(p -> p.getId().equals(postID))
55 | .findFirst()
56 | .orElseThrow(() -> new PostNotFoundException("Cannot find post with id:" + postID));
57 | }
58 |
59 |
60 | /**
61 | * Load top ten posts from DB *Long running method
62 | */
63 | public List getTopPosts() {
64 | try {
65 | TimeUnit.SECONDS.sleep(1);
66 | } catch (InterruptedException e) {
67 | e.printStackTrace();
68 | }
69 | return posts;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------