Spring Boot Cache Actual EhCache

Spring boot uses SimpleCacheConfiguration by default, even using Concurrent MapCache Manager to implement caching. But switching to other cache implementations is also simple.

pom file

Introducing corresponding jar packages into pom

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

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-jpa</artifactId>
	</dependency>

	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
	</dependency>

	<dependency>
		<groupId>org.apache.commons</groupId>
		<artifactId>commons-dbcp2</artifactId>
	</dependency>
	
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-cache</artifactId>
	</dependency>

	<dependency>
		<groupId>net.sf.ehcache</groupId>
		<artifactId>ehcache</artifactId>
	</dependency>

</dependencies>

configuration file

The configuration files needed by EhCache only need to be placed in the classpath, and Spring Boot scans automatically.

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <cache name="people" maxElementsInMemory="1000"/>
</ehcache>

You can also specify the location of the EhCache configuration file by configuring it in the application.properties file, such as:

spring.cache.ehcache.config= #  ehcache profile address

Spring Boot automatically configures EhCacheCacheMannager's Bean for us.

Key Service

package com.xiaolyuh.service.impl;

import com.xiaolyuh.entity.Person;
import com.xiaolyuh.repository.PersonRepository;
import com.xiaolyuh.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class PersonServiceImpl implements PersonService {
    @Autowired
    PersonRepository personRepository;

    @Override
    @CachePut(value = "people", key = "#person.id")
    public Person save(Person person) {
        Person p = personRepository.save(person);
        System.out.println("by id,key by:" + p.getId() + "Data is cached");
        return p;
    }

    @Override
    @CacheEvict(value = "people")//2
    public void remove(Long id) {
        System.out.println("Deleted id,key by" + id + "Data caching");
        //No actual deletion is done here.
    }

    @Override
    @Cacheable(value = "people", key = "#person.id")//3
    public Person findOne(Person person) {
        Person p = personRepository.findOne(person.getId());
        System.out.println("by id,key by:" + p.getId() + "Data is cached");
        return p;
    }
}

Controller

package com.xiaolyuh.controller;

import com.xiaolyuh.entity.Person;
import com.xiaolyuh.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CacheController {

    @Autowired
    PersonService personService;

    @Autowired
    CacheManager cacheManager;

    @RequestMapping("/put")
    public long put(@RequestBody Person person) {
        Person p = personService.save(person);
        return p.getId();
    }

    @RequestMapping("/able")
    public Person cacheable(Person person) {
        System.out.println(cacheManager.toString());
        return personService.findOne(person);
    }

    @RequestMapping("/evit")
    public String evit(Long id) {

        personService.remove(id);
        return "ok";
    }

}

Startup class

@SpringBootApplication
@EnableCaching// Open the cache and specify what needs to be displayed
public class SpringBootStudentCacheApplication {

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

Test class

package com.xiaolyuh;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.util.HashMap;
import java.util.Map;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import net.minidev.json.JSONObject;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootStudentCacheApplicationTests {

    @Test
    public void contextLoads() {
    }

    private MockMvc mockMvc; // The MVC object is simulated and initialized by MockMvcBuilders.webAppContextSetup(this.wac).build().

    @Autowired
    private WebApplicationContext wac; // Injecting Web Application Context  

//    @Autowired  
//    private MockHttpSession session; // injection of simulated http session  
//      
//    @Autowired  
//    private MockHttpServletRequest request; //Inject simulated http request\  

    @Before // Initialize work before testing starts  
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }

    @Test
    public void testAble() throws Exception {
        for (int i = 0; i < 2; i++) {
            MvcResult result = mockMvc.perform(post("/able").param("id", "2"))
                    .andExpect(status().isOk())// Simulate sending get requests to testRest
                    .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))// The media type text/plain of the expected return value;
                    // charset=UTF-8
                    .andReturn();// Returns the result of executing the request

            System.out.println(result.getResponse().getContentAsString());
        }
    }

}

Print log

From the above, we can see that the first time to go is the database, and the second time to go is the cache.

Source code: https://github.com/wyh-spring-ecosystem-student/spring-boot-student/tree/releases

spring-boot-student-cache-ehcache project

Laying-cache, a multi-level caching framework for monitoring This is an implementation of my open source multi-level caching framework. If you are interested, take a look at it.

Tags: Programming Spring Ehcache Java Junit

Posted on Wed, 09 Oct 2019 20:14:25 -0700 by judgy