Cache usage of Spring boot

Posted by munkee on Wed, 09 Mar 2022 13:43:20 +0100

The Spring framework provides caching abstraction APIs for different caching products. The use of the API is very simple, but the function is very powerful. Today we will see annotation based Java configuration on the cache. Please note that we can also implement similar functions through XML configuration. @EnableCaching It supports spring's annotation driven cache management function. In the spring boot project, we need to add it to the annotated boot application class @ SpringBootApplication. Spring provides a concurrent hashmap as the default cache by default, but we can also override the CacheManager to easily register external cache providers. @Cacheable It is used at the method level to let spring know that the response of the method is cacheable. Spring manages the request / response of this method to the cache specified in the annotation properties. For example, @ Cacheable ("cache-name1", "cache-name2"). @The Cacheable annotation has more options. Just as we can specify the key of the cache from the request of the method, if not specified, spring uses all class fields and uses them as the cache key (mainly HashCode) to maintain the cache, but we can override this behavior by providing key information:

@Cacheable(value="books", key="#isbn")
public Book findStoryBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

@Cacheable(value="books", key="#isbn.rawNumber")
public Book findStoryBook (ISBN isbn, boolean checkWarehouse, boolean includeUsed)

@Cacheable(value="books", key="T(classType).hash(#isbn)")
public Book findStoryBook (ISBN isbn, boolean checkWarehouse, boolean includeUsed)

We can also use conditional caching. For example,

@Cacheable(value="book", condition="#name.length < 50")
public Book findStoryBook (String name)

@CachePut Sometimes we need to manually operate the cache so that we can put (update) the cache before the method call. This method allows us to update the cache and execute the annotated method. Spring executes the annotated method and puts its results into the cache (according to the @ CachePut option). It supports the same options as @ Cacheable and should be used for cache population rather than method flow optimization. Note that @ CachePut and @ Cacheable annotations for the same method are generally discouraged because they have different behaviors. Although the latter results in execution by using the cache skip method, the former enforces to perform cache updates. This can lead to unexpected behavior, and such declarations should be avoided except in specific corner situations, such as comments with conditions to exclude them from each other. @CacheEvict It can be used when we need to delete the previously loaded master data from the cache. When the CacheEvict annotation method will be executed, it will clear the cache. We can specify the key here to delete the cache. If we need to delete all entries in the cache, we need to use allEntries=true. This option comes in handy when you need to clear the entire cache area - instead of culling each entry one by one (which takes a long time because it is inefficient), all entries are deleted in one operation. @Caching Use this annotation when both CachePut and CacheEvict are required. Spring launches integration with the following cache providers. Spring boot uses default options for automatic configuration. If these options exist in the classpath and we have enabled caching through @ EnableCaching in the spring boot application.

JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
EhCache 2.x
Hazelcast
Infinispan
Couchbase
Redis
Caffeine
Simple cache

We can override the specific caching behavior in Spring starter by overriding the cache provider specific settings - for example

spring.cache.infinispan.config=infinispan.xml

Use case 1. Use cache:

@Service
public class StudentService
{
    @Cacheable("student")
    public Student getStudentByID(String id)
    {
        try
        {
            System.out.println("Going to sleep for 5 Secs.. to simulate backend call.");
            Thread.sleep(1000*5);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }

        return new Student(id,"Sajal" ,"V");
    }
}

The service layer method is annotated @ Cacheable("student"), which enables caching in this specific method, and the cache name is "student". In this getStudentByID() method, we use the intentional 5-second delay thread sleep(1000*5). This is just to know whether the response comes from the cache or the real back end. 2. REST front end:

@RestController
public class StudentController
{

    @Autowired
    StudentService studentService;

    @GetMapping("/student/{id}")
    public Student findStudentById(@PathVariable String id)
    {
        System.out.println("Searching by ID  : " + id);

        return studentService.getStudentByID(id);
    }
}

3. Enable caching:

@SpringBootApplication
@EnableCaching
public class SpringCacheApplication {

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

Complete source code

https://howtodoinjava.com/spring-boot2/spring-boot-cache-example/?utmsource=feedburner&utmmedium=twitter&utm_campaign=Feed%3A+HowToDoInJava+%28How+to+do+in+JAVA%29