STACKJAVA

Code ví dụ Spring Boot Caching (@Cacheable, @CacheEvict, @CachePut, @Caching)

Code ví dụ Spring Boot Caching (@Cacheable, @CacheEvict, @CachePut, @Caching)

Trong bài này mình sẽ làm ví dụ về spring boot cache để lưu dữ liệu trong in memory cache làm tăng tốc độ truy vấn dữ liệu

 

1. Code ví dụ Spring Boot Caching (@Cacheable, @CacheEvict, @CachePut, @Caching)

Cấu trúc project:

Thư viện sử dụng:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>stackjava.com</groupId>
    <artifactId>spring-boot-caching</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-caching</name>
    <description>Demo caching with spring boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Thư viện spring-boot-starter-cache để dùng cache

File models:

package stackjava.com.springbootcaching.models;

public class User {
    private int id;
    private String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" + "id=" + id + ", name='" + name + '\'' + '}';
    }
}

File services:

package stackjava.com.springbootcaching.services;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import stackjava.com.springbootcaching.models.User;

@Service
public class UserService {

    @Cacheable("user")
    public User findUserById(int id) {
        simulateSlowService();
        return new User(id, "Any name");
    }

    // Don't do this at home
    private void simulateSlowService() {
        try {
            long time = 3000L;
            Thread.sleep(time);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
    }

    @CacheEvict("user")
    public void clearCacheById(int id) {
    }

    @CacheEvict(value = "user", allEntries = true)
    public void clearCache() {
    }

    @CachePut(value = "user")
    public User reloadAndFindUserById(int id) {
        simulateSlowService();
        return new User(id, "reload Any name");
    }
}

File SpringBootCachingApplication.java

package stackjava.com.springbootcaching;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import stackjava.com.springbootcaching.services.UserService;

@SpringBootApplication
@EnableCaching
public class SpringBootCachingApplication implements CommandLineRunner {
    private static final Logger logger = LoggerFactory.getLogger(SpringBootCachingApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(SpringBootCachingApplication.class, args);
    }

    @Autowired
    private UserService userService;

    @Override
    public void run(String... args) {
        logger.info("------------------ demo @Cacheable --------------------");
        logger.info("find user with id = 1: {}", userService.findUserById(1));
        logger.info("find user with id = 1: {}", userService.findUserById(1));
        logger.info("find user with id = 2: {}", userService.findUserById(2));
        logger.info("find user with id = 2: {}", userService.findUserById(2));

        logger.info("------------------ demo @CacheEvict --------------------");
        userService.clearCache();
        logger.info("find user with id = 1: {}", userService.findUserById(1));
        logger.info("find user with id = 2: {}", userService.findUserById(2));

        logger.info("------------------ demo @CachePut --------------------");
        logger.info("reload and find user with id = 1: {}", userService.reloadAndFindUserById(1));
        logger.info("find user with id = 1: {}", userService.findUserById(1));
        logger.info("find user with id = 2: {}", userService.findUserById(2));
    }
}

Trong ví dụ này mình ko sử dụng thư viện spring-boot-web nên mình sẽ dùng CommandLineRunner để chạy chương trình.

Annotation @EnableCaching là bắt buộc, nó sử dụng để spring context có thể tìm được các annotation @Cacheable, @CacheEvict, @CachePut

2. Demo và giải thích kết quả

Chạy file SpringBootCachingApplication.java

Kết quả:

2020-06-12 16:18:37.221  INFO 14016 --- : ------------------ demo @Cacheable --------------------
2020-06-12 16:18:40.247  INFO 14016 --- : find user with id = 1: User{id=1, name='Any name'}
2020-06-12 16:18:40.253  INFO 14016 --- : find user with id = 1: User{id=1, name='Any name'}
2020-06-12 16:18:43.255  INFO 14016 --- : find user with id = 2: User{id=2, name='Any name'}
2020-06-12 16:18:43.255  INFO 14016 --- : find user with id = 2: User{id=2, name='Any name'}
2020-06-12 16:18:43.255  INFO 14016 --- : ------------------ demo @CacheEvict --------------------
2020-06-12 16:18:46.256  INFO 14016 --- : find user with id = 1: User{id=1, name='Any name'}
2020-06-12 16:18:49.256  INFO 14016 --- : find user with id = 2: User{id=2, name='Any name'}
2020-06-12 16:18:49.256  INFO 14016 --- : ------------------ demo @CachePut --------------------
2020-06-12 16:18:52.258  INFO 14016 --- : reload and find user with id = 1: User{id=1, name='reload Any name'}
2020-06-12 16:18:52.259  INFO 14016 --- : find user with id = 1: User{id=1, name='reload Any name'}
2020-06-12 16:18:52.259  INFO 14016 --- : find user with id = 2: User{id=2, name='Any name'}

Xem log chúng ta thấy:

Okay, Done!

Download code ví dụ trên tại đây hoặc tại: https://github.com/stackjava/spring-boot-caching

References: https://spring.io/guides/gs/caching/