├── 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 | --------------------------------------------------------------------------------