Spring Cache Annotations @cacheable, @CacheEvict, @CachePut use starting with 3.1, spring introduces 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 that some methods use cache N to configure spring's support for the cache and spring's support for transaction management, as well as the annotations-based and XML-based configuration of spring's support for the cache. Let's take a look at the annotation-based approach first. 1annotation-based support spring provides us with several annotations to support 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.1The Value property specifies that the cache Name 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. @Cacheable ("Cache1")//The cache happened on cache1. PublicUser find (Integer id) {returnnull; } @Cacheable ({"Cache1", "Cache2"})//The cache occurred on Cache1 and Cache2. PublicUser find (Integer id) {returnnull; } 1.1.2using the key property to customize the key 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") PublicUser find (Integer id) {returnnull; } @Cacheable (Value= "Users", key= "#p0") PublicUser find (Integer id) {returnnull; } @Cacheable (Value= "Users", key= "#user. ID") Publicuser Find (user user) {returnnull; } @Cacheable (Value= "Users", key= "#p0. ID") Publicuser Find (user user) {returnnull; In addition to the above using the method parameter 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. Property Name Description Example methodname Current method name #root.methodnamemethod current method #root.method.nametarget the currently called object # Root.targettargetclass an array of Class#root.targetclassargs current method arguments for the currently called Object #root.args[0]caches The cache#root.caches[used by the currently invoked method0].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") Publicuser Find (user user) {returnnull; } 1.1.3The Condition property specifies the condition that occurs when 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") Publicuser Find (user user) {System.out.println ("Find user by user" +user); returnuser; } 1.2@CachePut in a spring cache-enabled environment, for a method that uses @cacheable annotations, 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, the method is removed directly from the cache The result is returned, otherwise it is executed and the returned result is 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")//The method is executed each time and the result is stored in the specified cache PublicUser find (Integer id) {returnnull; } 1.3@CacheEvict @CacheEvict is used to annotate a method or class that needs to clear the cache element. 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.1The Allentries property 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 voidDelete (Integer id) {SYSTEM.OUT.PRINTLN ("Delete User by ID:" +ID); } 1.3.2The beforeinvocation Property cleanup 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 of 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 voidDelete (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) }) PublicUser find (Integer id) {returnnull; } 1.5using 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@Interfacemycacheable {} The same effect can be achieved by using @mycacheable for labeling on the method we need to cache. @MyCacheable PublicUser FindByID (Integer id) {SYSTEM.OUT.PRINTLN ("Find User by ID:" +ID); User User=NewUser (); User.setid (ID); User.setname ("Name" +ID); returnuser; } 2Configuring spring support for the cache2.1declaring support for the cache2.1.1based on annotations to configure spring's 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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://Www.springframework.org/schema/cachehttp://www.springframework.org/schema/cache/spring-cache.xsd "><cache:annotation-driven/> </beans> <cache:annotation-driven/> have a cache-The Manager attribute is used to specify the name of the bean that is currently used by the CacheManager, which is cachemanager by default, so we can not specify this parameter when our CacheManager ID is cachemanager. Otherwise, we'll have to specify. <cache:annotation-driven/>You 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/> You can also specify a Proxy-target-class property that indicates whether you want 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, but it is important to note that when we set proxy-target-when class is true or mode is ASPECTJ, it is directly based on class, and the cache annotations defined on the interface are not recognized, and the corresponding spring cache does not work. It is important to note that<cache:annotation-driven/>will only look for cache annotations that define @cacheable such as the one under the same applicationcontext. 2.1.2XML-based 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 cacheThe-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. You can also specify Cache:cacheable, Cache:cache-put, and cache:cache-under the cache:caching elementevict elements, similar to the @cacheable, @CachePut, and @cacheevict when using annotations. Let's look at an example:<cache:advice id= "Cacheadvice" cache-manager= "CacheManager" > <cache:caching cache= "Users" > <ca Che:cacheable method= "FindByID" key= "#p0"/> <cache:cacheable method= "Find" key= "#user. Id"/> <c Ache: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*"represents 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:advisor advice-ref= "cacheadvice" pointcut= "Execution (* com.xxx.userservice.* (..))" /> </aop:config>The above configuration indicates that the cacheadvice corresponding Cache:advice will be used for spring cache processing when any public method in the Com.xxx.UserService is called. More about Spring AOP is not within the scope of this article. 2.2Configuring CacheManager CacheManager is a spring-defined interface for managing the cache. Spring itself has provided us with two CacheManager implementations, one based on the Java API Concurrentmap and the other based on the third-party cache implementation--ehcache, if we need to use other types of caches, We can implement spring's CacheManager interface or Abstractcachemanager abstract class on our own. Here's a look at the two CacheManager configuration examples that spring has done for us. 2.2.1Concurrentmap-based configuration<bean id= "CacheManager"class= "Org.springframework.cache.support.SimpleCacheManager" > <property name= "caches" > <set> <beanclass= "Org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name= "xxx"/> </set> </pro Perty> </bean>The above configuration uses a Simplecachemanager, which contains a concurrentmapcache named "xxx". 2.2.2Ehcache-based configuration<!--Ehcache-<bean id= "CacheManager"class= "Org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref= "Ehcachemanager"/> <bean id= " Ehcachemanager "class= "Org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location= "Ehcache-spring.xml"/>The above configuration uses a spring-provided ehcachecachemanager to generate a spring CacheManager that receives a ehcache CacheManager, Because it's ehcache to actually cache the data. The CacheManager of Ehcache is generated through the Ehcachemanagerfactorybean provided by spring, which can generate a Ehcache CacheManager by specifying the location of the Ehcache configuration file. If not specified, the Ehcache.xml file under the Classpath root path will be taken according to the default rule of Ehcache, and if the file does not exist, get ehcache in the corresponding jar package Ehcache-failsafe.xml file as a configuration file. More about Ehcache here is not much to say, it does not belong to the content of this article, to learn more about Ehcache can refer to my previous release of the Ehcache series of articles, can also refer to official documents. 3There are two generation strategies for key generation policy keys, one for the default policy and one for custom policies. 3.1Default Policy The default key generation policy is generated by Keygenerator with the following default policy: N If the method has no arguments, use 0 as the key. n Use this parameter as key if there is only one argument. n If the argument is extra, use the hashcode of all parameters as key. If we need to specify our own default policy, then we can implement our own keygenerator and then specify the keygenerator that our spring cache uses to define our own keygenerator. When using annotation-based configuration , the Cache:annotation-driven the specified. <cache:annotation-driven key-generator= "Userkeygenerator"/> <bean id= "Userkeygenerator"class= "Com.xxx.cache.UserKeyGenerator"/>the use of XML-based configuration is specified by Cache:advice. <cache:advice id= "Cacheadvice" cache-manager= "CacheManager" key-generator= "Userkeygenerator" > </cache: Advice>It is important to note that the default generation strategy for all of the keys we use at this time is the same keygenerator. 3.2Custom Policy custom policy means 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") PublicUser find (Integer id) {returnnull; } @Cacheable (Value= "Users", key= "#p0") PublicUser find (Integer id) {returnnull; } @Cacheable (Value= "Users", key= "#user. ID") Publicuser Find (user user) {returnnull; } @Cacheable (Value= "Users", key= "#p0. ID") Publicuser Find (user user) {returnnull; In addition to the above using the method parameter 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. Property Name Description Example methodname Current method name #root.methodnamemethod current method #root.method.nametarget the currently called object # Root.targettargetclass an array of Class#root.targetclassargs current method arguments for the currently called Object #root.args[0]caches The cache#root.caches[used by the currently invoked method0].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") Publicuser Find (user user) {returnnull; } 4Spring's use of Ehcache, as described earlier in this article, is the spring built-in support for the cache, and we can also use the Ehcache CacheManager or Ehcache object by spring alone. By configuring Ehcachemanagerfactorybean and Ehcachefactorybean in the application context, We can then inject the corresponding Ehcache CacheManager and Ehcache objects into other spring bean objects for use. 4.1Ehcachemanagerfactorybean Ehcachemanagerfactorybean is a factorybean of spring's built-in CacheManager object that can produce Ehcache. It is possible to specify the path to the Ehcache configuration file used to create CacheManager through the property configlocation, usually the path of the Ehcache.xml file. If configlocation is not specified, the CacheManager is created using the default location profile, which is the logic that belongs to Ehcache itself. That is, if a ehcache.xml file exists under the Classpath root path, the file is used directly as the Ehcache configuration file, otherwise the Ehcache will be used.The ehcache-in-xxx.jarThe Failsafe.xml file is used as a configuration file to create the Ehcache CacheManager. In addition, if you do not want to create a CacheManager that uses the default name (defined in the Ehcache.xml file, or is defined internally by CacheManager), you can specify it through the Cachemanagername property. The following is an example of configuring Ehcachemanagerfactorybean. <!--definition CacheManager--<bean id= "CacheManager"class= "Org.springframework.cache.ehcache.EhCacheManagerFactoryBean" > <!--Specify the location of the configuration file--<property name= "C Onfiglocation "value="/web-inf/config/ehcache.xml "/> <!--specify new CacheManager name---<property name=" C Achemanagername "value=" Cachemanagername "/> </bean> 4.2Ehcachefactorybean Ehcachefactorybean is the Factorybean of Ehcache objects used to generate Ehcache. There are two important properties that we can specify when defining Ehcachefactorybean. One is the CacheManager property, which specifies the CacheManager object that will be used to get or create the Ehcache, or, if unspecified, gets or creates a default CacheManager by Cachemanager.create (). Another important property is CacheName, which indicates which of the Ehcache objects in the current Ehcachefactorybean corresponds to CacheManager, and if it is not specified by default, Beanname is used as cachename. If the Ehcache object of the corresponding CacheName does not exist in CacheManager, a cache object named CacheName will be created using CacheManager. In addition, we can specify the corresponding properties of the cache to be created by Ehcachefactorybean's Timetoidle, TimeToLive, and other properties. Note that these properties only work for the new cache that does not exist in the CacheManager cache, does not work for existing caches, and more property settings refer to the Spring API documentation. In addition, there are several properties that work for both existing and newly created caches: statisticsenabled, sampledstatisticsenabled, disabled, Blocking and Cacheeventlisteners, where the first four defaults are false and the last represents the specified Cacheeventlistener for the current cache. The following is an example of defining Ehcachefactorybean. <!--definition CacheManager--<bean id= "CacheManager"class= "Org.springframework.cache.ehcache.EhCacheManagerFactoryBean" > <!--Specify the location of the configuration file--<property name= "C Onfiglocation "value="/web-inf/config/ehcache.xml "/> <!--specify new CacheManager name---<property name=" C Achemanagername "value=" Cachemanagername "/> </bean> <!--define a Ehcache--<bean id=" Usercache "class= "Org.springframework.cache.ehcache.EhCacheFactoryBean" > <property name= "cachename" value= "User"/> < Property Name= "CacheManager" ref= "CacheManager"/> </bean>
Spring Cache @cachable