Starting with 3.1, spring introduced support for the cache. The methods and principles used are similar to spring's support for transaction management. Spring Cache is a method of action, and the core idea is that when we call a caching method, the method parameter and the return result are stored in the cache as a key-value pair, and the method is no longer executed the next time the same parameter is invoked. Instead, the results are returned directly from the cache. So when using the spring cache we have to make sure that our cached methods have the same return result for the same method parameters.
Using spring cache requires that we do two things:
N declares some methods to use the cache
n Configuring spring support for the cache
As with spring's support for transaction management, Spring's support for caches also has annotations-based and XML-based configurations. Let's take a look at the annotation-based approach first.
1. Annotation-based support
Spring provides us with several annotations to support the spring Cache. Its core is mainly @cacheable and @cacheevict. The method that uses the @cacheable tag is executed after the spring cache caches its return results, and the method that uses the @cacheevict tag removes some elements of the spring cache before or after the method executes. Let's take a look at some of the annotations provided by spring based annotations on cache support in detail.
1.1 @Cacheable
@Cacheable can be marked on a method or on a class. When tagged on a method means that the method is cached, and when tagged on a class It means that all methods of the class are cache-enabled. For a cache-enabled method, spring caches its return value after it is called, ensuring that the next time the same parameter is used to execute the method, the result can be obtained directly from the cache without having to execute the method again. Spring caches the return value of the method as a key-value pair, and the value is the return result of the method, and spring supports two strategies, the default policy and the custom policy, which are explained later. It is important to note that caching is not triggered when a caching-enabled method is invoked inside the object. @Cacheable can specify three properties, value, key, and condition.
1.1.1 The Value property specifies the cache name
The Value property must be specified, which means that the return value of the current method is cached on which cache, corresponding to the name of the cache. It can be a cache or multiple caches, which is an array when multiple caches need to be specified.
The @Cacheable ("cache1")//cache occurs on cache1.
Public User find (Integer ID) {
Returnnull;
}
The @Cacheable ({"Cache1", "Cache2"})//cache occur on cache1 and cache2
Public User find (Integer ID) {
Returnnull;
}
1.1.2 Using the key property to customize the key
The key property is used to specify the key that corresponds to the return result of the spring cache method. This property supports Springel expressions. When we do not specify this property, spring uses the default policy to generate the key. Let's take a look at the custom policy here, as the default policy is described separately later in this article.
The custom policy is that we can specify our key through the El expression of spring. The El expressions here can use the method parameters and their corresponding properties. We can use "#参数名" or "#p参数index" directly when using method parameters. Here are a few examples of using parameters as keys.
@Cacheable (value= "Users", key= "#id")
Public User find (Integer ID) {
Returnnull;
}
@Cacheable (value= "Users", key= "#p0")
Public User find (Integer ID) {
Returnnull;
}
@Cacheable (value= "Users", key= "#user. ID")
Public user find (user user) {
Returnnull;
}
@Cacheable (value= "Users", key= "#p0. ID")
Public user find (user user) {
Returnnull;
}
In addition to the above usage parameters as key, Spring also provides us with a root object that can be used to generate the key. The root object allows us to obtain the following information.
/tbody>
Property name
Description
Example
P>methodname
Current method name
#root. MethodName
method
Current method
#root. Method.name
Target
The currently called object
#root. Target
Targetclass
Class of the object currently being called
#root. Targetclass
Args
An array of current method parameters
#root. args[0]
Caches
The currently invoked method uses the cache
#root. Caches[0].name
We can also omit "#root" when we want to use the root object's property as key, because spring uses the root object's properties by default. Such as:
@Cacheable (value={"users", "XXX"}, key= "Caches[1].name")
Public user find (user user) {
Returnnull;
}
1.1.3 Condition property specifies the condition that occurs
Sometimes we may not want to cache a method with all of the returned results. This functionality can be achieved through the condition property. The Condition property defaults to NULL, which means that all invocation scenarios are cached. The value is specified by the Springel expression, which is true when the cache is processed, and when false indicates that no caching is processed, that method executes once each time the method is called. The following example indicates that caching occurs only if the ID of the user is even.
@Cacheable (value={"Users"}, key= "#user. Id", condition= "#user. id%2==0")
Public user find (user user) {
System.out.println ("Find User by user" + user);
return user;
}
1.2 @CachePut
In a spring cache-enabled environment, for a method that uses the @cacheable annotation, spring checks to see if there is a cache element of the same key in the cache before each execution, and if it does not execute the method, it returns the result directly from the cache. Otherwise it will execute and the returned result will be stored in the specified cache. @CachePut can also declare a method that supports caching functionality. Unlike @cacheable, a method that uses the @cacheput annotation does not check the cache for previous results before execution, but executes the method every time and deposits the execution result in the specified cache as a key-value pair.
@CachePut can also be labeled on the class and on the method. The properties we can specify when using @cacheput are the same as @cacheable.
@CachePut ("Users")//Executes the method each time and stores the result in the specified cache
Public User find (Integer ID) {
Returnnull;
}
1.3 @CacheEvict
The @CacheEvict is used to label the method or class on which the cache element needs to be cleared. When marked on a class, the execution of all the methods in it indicates that the cached purge operation is triggered. @CacheEvict properties that can be specified are value, key, condition, allentries, and Beforeinvocation. The semantics of value, key, and condition are similar to those of the @cacheable counterparts. That is, value indicates which cache (corresponding to the cache name) The purge operation occurred on, and key indicates which key needs to be purged, and key;condition generated using the default policy, if unspecified, represents the condition in which the purge operation occurs. Let's take a look at the new two properties Allentries and Beforeinvocation.
1.3.1 allentries Properties
Allentries is a Boolean type that indicates whether all elements in the cache need to be cleared. The default is false, which means it is not required. When Allentries is specified as true, the Spring cache ignores the specified key. Sometimes we need the cache to clear all the elements, which is more efficient than a clear element.
@CacheEvict (value= "users", Allentries=true)
public void Delete (Integer id) {
System.out.println ("Delete User by ID:" + ID);
}
1.3.2 beforeinvocation Properties
The purge operation is triggered by default after the corresponding method executes successfully, that is, the method does not trigger a purge operation if it fails to return successfully because it throws an exception. Using Beforeinvocation can change the time that the purge operation is triggered, and when we specify that the property value is true, spring clears the specified element in the cache before calling the method.
@CacheEvict (value= "users", Beforeinvocation=true)
public void Delete (Integer id) {
System.out.println ("Delete User by ID:" + ID);
}
In fact, in addition to using @cacheevict to clear the cache element, when we use Ehcache as the implementation, we can also configure the Ehcache own eviction policy, which is specified by the Ehcache configuration file. Since Ehcache is not the focus of this article, it's not a lot to go through here, and for more information about Ehcache, check out my column on Ehcache.
1.4 @Caching
@Caching annotations Allow us to specify multiple spring cache-related annotations at the same time on a method or class. It has three properties: cacheable, put, and evict, which are used to specify @cacheable, @CachePut, and @cacheevict, respectively.
@Caching (cacheable = @Cacheable ("Users"), evict = {@CacheEvict ("cache2"),
@CacheEvict (value = "Cache3", Allentries = True)})
Public User find (Integer ID) {
Returnnull;
}
1.5 using custom annotations
Spring allows us to use custom annotations when configuring cacheable methods, provided that the corresponding annotations must be annotated on the custom annotations. If we have one of the following custom annotations that are annotated with @cacheable.
@Target ({elementtype.type, elementtype.method})
@Retention (Retentionpolicy.runtime)
@Cacheable (value= "users")
Public @interface Mycacheable {
}
The same effect can be achieved by using @mycacheable on the method we need to cache.
@MyCacheable
Public User FindByID (Integer ID) {
System.out.println ("Find User by ID:" + ID);
User user = new user ();
User.setid (ID);
User.setname ("Name" + ID);
return user;
}
2. Configuring Spring support for the cache
2.1 declaring support for the cache
2.1.1 Based on annotations
To configure spring support for note-based caches, we first need to introduce the cache namespace in spring's configuration file, followed by <cache:annotation-driven/> You can enable spring support for note-based caches.
<?xml version= "1.0" encoding= "UTF-8"?>
<beans xmlns= "Http://www.springframework.org/schema/beans"
Xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance"
Xmlns:cache= "Http://www.springframework.org/schema/cache"
Xsi:schemalocation= "Http://www.springframework.org/schema/beans
Http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
Http://www.springframework.org/schema/cache
Http://www.springframework.org/schema/cache/spring-cache.xsd ">
<cache:annotation-driven/>
</beans>
<cache:annotation-driven/> has a Cache-manager property to specify the name of the bean that is currently used by the CacheManager, which is CacheManager by default. So when our CacheManager ID is CacheManager We can not specify this parameter, otherwise we need to specify.
<cache:annotation-driven/> can also specify a mode property, and the optional values are proxy and ASPECTJ. The default is to use proxy. When mode is proxy, the spring cache does not function until the cache method is called externally, which means that the spring cache does not work if a cache method is invoked within its declared object. There is no such problem when mode is ASPECTJ. When using proxy, only annotations such as @cacheable on the public method will work, and if you need a method on a non-public method, you can also set mode to ASPECTJ when using spring cache.
In addition,,<cache:annotation-driven/> can also specify a Proxy-target-class property that indicates whether to proxy class and false by default. The @cacheable, @cacheEvict, etc. we mentioned earlier can also be labeled on the interface, which is not a problem for interface-based proxies. However, it is important to note that when we set Proxy-target-class to TRUE or mode to ASPECTJ, it is directly based on class, and the cache annotations defined on the interface are not recognized, and the corresponding spring The cache won't work either.
It is important to note that <cache:annotation-driven/> will only look for cache annotations that are defined under the same ApplicationContext @cacheable.
2.1.2 based on XML configuration
In addition to using annotations to declare support for the cache, spring also supports the use of XML to declare support for the cache. This is mainly done through cache:advice similar to the Aop:advice. A cache:advice element is defined under the cache namespace to define a advice for the cache. It needs to specify a Cache-manager property, which defaults to CacheManager. Cache:advice you can specify more than one cache:caching element, which is somewhat similar to the @caching annotation when using annotations. The cache:cacheable, Cache:cache-put, and cache:cache-evict elements can be specified under the Cache:caching element, similar to the @cacheable when using annotations, @ Cacheput and @cacheevict. Let's look at an example:
<cache:advice id= "Cacheadvice" cache-manager= "CacheManager" >
<cache:caching cache= "Users" >
<cache:cacheable method= "FindByID" key= "#p0"/>
<cache:cacheable method= "Find" key= "#user. Id"/>
<cache:cache-evict method= "DeleteAll" all-entries= "true"/>
</cache:caching>
</cache:advice>
The above configuration defines a cache:advice named Cacheadvice that specifies the cache FindByID method and the Find method to the cache named users. The method here can also use the wildcard character "*", such as "find*" for any method that starts with "find".
With Cache:advice, we also need to introduce an AOP namespace, and then aop:config specify which pointcut to apply to the defined Cacheadvice. Such as:
<aop:config proxy-target-class= "false" >
<aop:adviso