Spring defines the CacheManager and Cache interfaces to unify different caching technologies. Such as JCache, EhCache, Hazelcast, Guava, Redis, etc. When using Spring to integrate Cache, we need to register the implemented CacheManager beans. Spring Boot default SimpleCacheConfiguration, which USES ConcurrentMapCacheManager to implement caching.
CacheManager: a CacheManager that manages various cache components
CacheManager | describe |
---|---|
SimpleCacheManager | Use a checkpoint Collection to store the cache, primarily for testing purposes |
ConcurrentMapCacheManager | Use ConcurrentMap to store the cache |
NoOpCacheManager | This is for testing only and will not actually store the cache |
EhCacheCacheManager | Use EhCache as a caching technology |
GuavaCacheManager | Use Guava as a caching technology |
HazelcastCacheManager | Use Hazelcast as a caching technique |
JCacheCacheManager | Implementation of the JCache (JSR-107) standard is supported as a caching technology |
RedisCacheManager | Use Redis as the caching technology |
Cache comment details
-
@cacheconfig: Used to configure common cache configurations that will be used in this class. Here @cacheconfig (cacheNames = “Users “) is configured to store the contents returned from this data access object in a cache object named Users. We can also use @cacheable to specify the name of the cache set without using this annotation.
-
@cacheable: For method configuration, the result of a method can be cached based on its request parameters. At the same time, during the query, the database will be obtained from the cache first. If the database does not exist, the access to the database will be initiated. This annotation takes the following parameters:
-
Value, cacheNames: Two identical arguments (cacheNames is new to Spring 4 as an alias for Value) that specify the collection name for cache storage. With the addition of @Cacheconfig in Spring 4, the value attribute, which was required in Spring 3, is no longer required.
-
By default, all the parameters of a function are used as the key. If you want to use the SpEL table, for example, @cacheable (key = “#p0”) : The first parameter of the function is used as the cache key. More details about SpEL expressions can be found in the official documentation.
-
Condition: The condition of the cache object. It is not required, and SpEL expressions are used. Only content that meets the expression conditions will be cached, for example: @cacheable (key = “#p0”, condition = “#p0.length() < 3”); Cacheable(key = “#p0”, condition = “#p0.length() < 3”);
-
Unless: Another cache condition parameter, which is not required and requires an SpEL expression. It differs from the condition argument in its timing. The condition is judged after the function is called, so it can be judged on result.
-
KeyGenerator: Specifies the key generator. It is not required. If you need to specify a custom key generator, we need to achieve org. Springframework. Cache. The interceptor. The KeyGenerator interface, and use this parameter to specify. Note that this parameter and key are mutually exclusive.
-
CacheManager: specifies which cacheManager to use. It is not required. This parameter is required only when there are multiple hosts.
-
CacheResolver: Specifies which cache parser to use. It is not required. By org. Springframework. Cache. The interceptor. CacheResolver interface to implement their own caching parser, and the parameters are specified.
-
-
@ CachePut: Configuration on the way, can according to the parameters defined conditions for caching, which unlike @ Cacheable, it won’t go to check whether there is in the cache before out of the results, but each time to execute the method, and the execution results in the form of a key/value pair in the cache, so it is mainly used for the data of new and modified operation. Its parameters are similar to @cacheable. For details, see @cacheable.
-
@cacheevict: configured for functions, usually used in delete methods, to remove data from the cache. In addition to the same arguments as @cacheable, it takes the following two arguments:
-
AllEntries: not required, default is false. When true, all data is removed.
-
BeforeInvocation: Not required, defaults to false and removes data after invocation of the method; When true, the data is removed before the method is called.
-
Setting up the Spring Boot default cache
Enabling Cache Support
Add @enablecaching to the startup class to EnableCaching to perform automatic scanning.
@SpringBootApplication
@EnableCaching // Enable caching
public class CacheApplication {
public static void main(String[] args) { SpringApplication.run(CacheApplication.class, args); }}Copy the code
Add a spring-boot-starter-cache dependency
Add a spring-boot-starter-cache dependency to pum.xml.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
Copy the code
To prepare data
Simulated database data
/** * data factory, simulate the data of the database **@author star
**/
public class DataFactory {
private DataFactory(a) {}private static List<UserDto> userDtoList;
static {
// Initialize the collection
userDtoList = new ArrayList<>();
UserDto user = null;
for (int i = 0; i < 10; i++) {
user = new UserDto();
user.setName("star" + i);
user.setAge("2"+ i); userDtoList.add(user); }}public static List<UserDto> getUserDaoList(a) {
returnuserDtoList; }}Copy the code
Write the cache business code
- Write the DAO layer
/**
* UserRepository
*
* @author star
**/
@Repository
public class UserRepository {
/** * Get user information */
public UserDto getUser(String username) {
UserDto user = getUserFromList(username);
return user;
}
/** * Delete user information */
public List<UserDto> deleteUser(String username) {
List<UserDto> userDaoList = DataFactory.getUserDaoList();
userDaoList.remove(getUserFromList(username));
return userDaoList;
}
/** * New data */
public List<UserDto> save(String username) {
// Add to collection
List<UserDto> userDaoList = DataFactory.getUserDaoList();
for (UserDto userDto : userDaoList) {
// The same data cannot be added repeatedly
if (Objects.equals(userDto.getName(), username)) {
return userDaoList;
}
}
UserDto user = new UserDto();
user.setName(username);
user.setAge("50");
userDaoList.add(user);
return userDaoList;
}
/** * Filter username data from the simulated data set */
private UserDto getUserFromList(String username) {
List<UserDto> userDaoList = DataFactory.getUserDaoList();
for (UserDto user : userDaoList) {
if (Objects.equals(user.getName(), username)) {
returnuser; }}return null; }}Copy the code
- Write the Service layer
/**
* UserService
*
* @author star
**/
@Service
@CacheConfig(cacheNames = "users")// Specify the cache name, which is global in this class
public class UserService {
@Autowired
private UserRepository userRepository;
/** * Cache key is the data of username to cache users, * if no key is specified, the method parameter is stored in cache as key */
@Cacheable(key = "#username")
public UserDto getUser(String username) {
System.out.println("Get data from the database instead of reading from the cache");
return userRepository.getUser(username);
}
/** * Add or update data in cache */
@CachePut(key = "#username")
public List<UserDto> save(String username) {
return userRepository.save(username);
}
/** * delete key from cache users */
@CacheEvict(key = "#username")
public List<UserDto> deleteUser(String username) {
System.out.println("Delete data from the database, as well as data in the cache");
returnuserRepository.deleteUser(username); }}Copy the code
- Writing the Controller layer
/**
* CacheResource
*
* @author star
**/
@RestController
@RequestMapping("/api")
public class CacheResource {
@Autowired
private UserService userService;
@GetMapping("/users/{username}")
public ResponseEntity<UserDto> getUser(@PathVariable String username) {
// Get data
UserDto user = userService.getUser(username);
return ResponseEntity.ok(user);
}
@PutMapping("/users/{username}")
public ResponseEntity<List<UserDto>> save(@PathVariable String username) {
List<UserDto> userDtoList = userService.save(username);
return ResponseEntity.ok(userDtoList);
}
@DeleteMapping("/users/{username}")
public ResponseEntity<List<UserDto>> delete(@PathVariable String username) {
List<UserDto> userDtoList = userService.deleteUser(username);
returnResponseEntity.ok(userDtoList); }}Copy the code
demo
To the interface http://localhost:8080/api/users/star1 GET data through many times to observe effect:
You can see caching enabled and in effect as follows: