Spring Boot uses the cache cache method
- 2020-12-22 17:39:09
- OfStack
1. What is cache Cache
The first word Cache comes from the CPU design
When CPU wants to read one data, it first looks it up from the CPU cache and immediately reads it and sends it to CPU for processing. If it is not found, it is read from the relatively slow memory and sent to CPU for processing. At the same time, the data block in which this data is located is transferred to the cache, so that later reads of the whole data block are carried out from the cache without calling the memory. It is this reading mechanism that makes the CPU cache hit ratio very high (most CPU are around 90%), meaning that 90% of the data read in a secondary session under CPU is in the CPU cache and only about 10% needs to be read from memory. This greatly saves CPU the time it takes to read the memory directly and eliminates the need to wait for CPU to read the data. In general, THE order in which CPU reads data is cache first and memory later.
Later on, the hard disk cache, then the application cache, browser cache, Web cache, and so on!
Cache is king!!
Spring Cache
Spring Cache is a complete set of application caching solution given by Spring for Spring applications.
Spring Cache itself does not provide a caching implementation, but instead uses interface and code specifications, configuration, annotations, and so on to enable you to use various Cache in Spring applications without worrying too much about the details of Cache. With Spring Cache, you can easily use it
Various cache implementations, including ConcurrentMap,Ehcache 2.ES46en,JCache,Redis, etc.
Definition of Cache in Spring
Sping about the definition of the cache, including in the interface org. springframework. cache. Cache,
It mainly provides the following methods
// According to the specified key Get the value
<T> T get(Object key, Class<T> type)
// Will specify the value according to the corresponding key And save it in the cache
void put(Object key, Object value);
// Retrieves the specified value based on the key
void evict(Object key)
It is not hard to see from the definition that Cache is in fact the structure of one ES66en-ES67en, and we operate the corresponding value through the specified key
Cache Manager
Cache is the collection of ES76en-ES77en, but in our project, there may be different Cache for various business topics, such as cache for users, Cache for departments, etc. These cache are logically separated. In order to distinguish these Cache, provides org springframework. cache. Various Cache CacheManager used to management. The interface contains only two methods
// Gets the cache for the topic by name
Cache getCache(String name);
// Gets a cache for all topics
Collection<String> getCacheNames();
In this interface, additions and deletions to Cache are not allowed, and should be done internally within the various CacheManager implementations, rather than publicly.
Annotation-based caching
Caching operations on data is not theoretically relevant to the business itself, and we should separate read and write operations on Cache from the main code logic. The way Spring separates is annotation-based (of course, so is JSR-107, etc.).
Spring provides a series of annotations, including @ Cacheable, @ CachePut, @ CacheEvict 1 series such as annotations to simplify our fuck do to cache, these annotations are located in org. springframework. cache. annotation package.
Example 2.
A simple example of Spring Boot using Spring Cache
Let's go step by step and build an example based on Spring Boot Cache
Create a new Spring Boot project and introduce the following dependencies
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
spring-boot-starter-cache is the key dependency of cache.
Modify the Application class to include the caching enabled annotation @EnableCaching
@SpringBootApplication
@EnableCaching
public class CacheSimpleApplication {
public static void main(String[] args) {
SpringApplication.run(CacheSimpleApplication.class, args);
}
}
The @EnableCache annotation initiates the caching mechanism of Spring, which enables the application to detect all cache-related annotations and get to work, as well as creating an CacheManager bean that can be injected by our application.
Create a new RestController class
@RestController
@RequestMapping("/")
public class CacheController {
@Autowired
private CacheTestService cacheTestService;
/**
* According to the ID Access to information
*
* @param id
* @return
*/
@GetMapping("{id}")
public String test(@PathVariable("id") String id) {
return cacheTestService.get(id);
}
/**
* Delete a ID The information of
*
* @param id
* @return
*/
@DeleteMapping("{id}")
public String delete(@PathVariable("id") String id) {
return cacheTestService.delete(id);
}
/**
* Save a ID The information of
*
* @param id
* @return
*/
@PostMapping
public String save(@RequestParam("id") String id, @RequestParam("value") String value) {
return cacheTestService.save(id, value);
}
/**
* With the new one ID The information of
*
* @param id
* @return
*/
@PutMapping("{id}")
public String update(@PathVariable("id") String id, @RequestParam("value") String value) {
return cacheTestService.update(id, value);
}
}
This class calls some Service to implement the actual add, delete, change and check operation.
Service implementation
Next, we will implement our Service
@Service
public class SimpleCacheTestServiceImpl implements CacheTestService {
private static final Logger logger = LoggerFactory.getLogger(SimpleCacheTestServiceImpl.class);
private final Map<String, String> enties = new HashMap<>();
public SimpleCacheTestServiceImpl() {
enties.put("1", "this no 1");
}
@Autowired
private CacheManager cacheManager;
@Override
@Cacheable(cacheNames = "test")
public String get(String id) {
// Record the time the data is generated for test comparisons
long time = new Date().getTime();
// Print used by cacheManager
logger.info("The cacheManager is" + cacheManager);
// When the data is not from cache When fetched inside, print log
logger.info("Get value by id=" + id + ", The time is " + time);
return "Get value by id=" + id + ",the value is" + enties.get(id);
}
@Override
public String delete(String id) {
return enties.remove(id);
}
@Override
public String save(String id, String value) {
logger.info("save value " + value + " with key " + id);
enties.put(id, value);
return value;
}
@Override
public String update(String id, String value) {
return enties.put(id, value);
}
}
The cache
First, run the code tests by annotating the get method with the @Cacheable annotation.
We used postman for the test, the test address was http://localhost:8080/1, the browser responded Get value by id=1,the value isthis no 1, the server console printed two lines of the log
Get value by id=1,the value isthis no 1
Get value by id=1, The time is 1516004770216
But when we refresh the browser address again, the browser returns normally, but the console no longer prints, because on the second call, Spring no longer executes the method, but directly fetches the cached value. Spring Cache cache the return value of a function as a function argument, key, cached in a cache called test.
Here we use the @Cacheable annotation. cacheNames in the annotation specifies which Cache is read here. In cacheName="test", cache is the cache object of id.
Deletes cached data
In the above program, if we request delete a specified value, through delete delete request sent to http: / / localhost: 8080/1, this time, the value has been deleted from the map, but we request to http get: / / localhost: 8080/1 of the time, still can get value, it is because we at the time of deleting data, not delete the data in the cache, but in front of the get method, the method of operation result is still preserved, Spring does not re-read, but reads the cache directly. At this point, we annotate the method
@Override
@CacheEvict(cacheNames = "test")
public String delete(String id) {
return enties.remove(id);
}
Test successively, call get request first, will show the return value is Get value by id=1,the value is 1 correctly
The delete request is then invoked. The data is removed from cache and map, and the get request is invoked again, when Get value by id=1,the value is null is returned, indicating that the value has indeed been removed from the cache.
Here we use the @CacheEvict annotation. cacheNames specifies which data in cache to delete, and the default is to use the method parameter as the key to delete
Update the cache
When the program gets here, if we run the post request, the body of the request is id=1 & value=new1, when the console prints save value new value1 with key 1, the code will save the value to map, but when we run the get request, we will find that the return value is still the same as before. This is what we can use
@Override
@CachePut(cacheNames = "test", key = "#id")
public String save(String id, String value) {
logger.info("save value " + value + " with key " + id);
return enties.put(id, value);
}
To re-execute the code, we first send the delete request to delete the data from map and cache. An post request is then sent and the data is written to map. When you finally send the get request, you will find that the values are now correctly fetched, and the console does not print the log of the data fetched from map.
The @CachePut annotation is used to write the return value of the method to the cache specified by cacheNames, given key.
Again, we need to add the @CachePut annotation to the put method so that the changes can also refresh the cached data.
At this point, a simple cache application containing add, delete, change and check is complete.
3. To highlight
A few notes
EnableCaching enables cache configuration Cacheable specifies that the return value of a method is cacheable. Specify the cache rule in the annotation property. Cacheput caches the return value of the method into the specified key CacheEvict deletes the specified cached dataPay attention to
Both @ES299en and @ES300en will put the execution result of the method into the cache according to the specified key. When @ES302en executes, it will first check whether there is data in the cache, and if there is data, it will read directly from the cache. If not, the method is executed and the return value is put into the cache, while @Cacheput executes the method first and then writes the result to the cache. Method 1 using @Cacheput will execute
Complete sample code in https: / / github com/ldwqh0 / cache - test
conclusion