Spring caching mechanism is very flexible and can be cached in any container or Bean Bean method, so this caching mechanism can be cached at any level JavaEE application.
Spring underlying cache buffer also need the help of other tools to achieve such EhCache (Hibernate caching tools), the top places unified API programming.
To use Spring cache, the following three steps
- 1. Import context to the Spring configuration file: namespace
- 2. Spring profile cache is enabled, in particular adding <cache: annotation-driven cache-manager = "Cache Manager ID" />
- 3. Configure cache manager, different cache to achieve different configurations, if it is EhCache, you need to configure a ehcache.xml
E.g
1 <?xml version="1.0" encoding="UTF-8"?> 2 <ehcache> 3 <diskStore path="java.io.tmpdir" /> 4 <-! Configure the default cache -> 5 <defaultCache 6 maxElementsInMemory="10000" 7 eternal="false" 8 timeToIdleSeconds="120" 9 timeToLiveSeconds="120" 10 maxElementsOnDisk="10000000" 11 diskExpiryThreadIntervalSeconds="120" 12 memoryStoreEvictionPolicy="LRU"/> 13 <! - Configure the buffer named users -> 14 <cache name="users" 15 maxElementsInMemory="10000" 16 eternal="false" 17 overflowToDisk="true" 18 timeToIdleSeconds="300" 19 timeToLiveSeconds="600" /> 20 </ehcache>
The above ehcache.xml configured with two cache, Spring in the Bean will be cached in the buffer area, the general, Spring Bean container, how many, how many buffers will be defined in the ehcache.
Spring then disposed in the configuration file cache manager follows, which is a first Bean Bean plant, to configure the CacheManager EhCache, the second is for the cache manager Bean Spring cache configuration, it will first Bean injecting a second Bean.
1 <cache:annotation-driven cache-manager="cacheManager" /> 2 3 <-! EhCache configuration of CacheManager 4 ehcache.xml specify the location of the file by configLocation -> 5 <bean id="ehCacheManager" 6 class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" 7 p:configLocation="classpath:ehcache.xml" 8 p:shared="false" /> 9 <-! EhCache configuration is based on the Cache Manager EhCache 10 and the injection of the buffer manager CacheManager Bean -> 11 <bean id="cacheManager" 12 class="org.springframework.cache.ehcache.EhCacheCacheManager" 13 percent: CacheManager-ref = "ehCacheManager"> 14 </bean>
Here is a complete Spring configuration,
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:p="http://www.springframework.org/schema/p" 5 xmlns:cache="http://www.springframework.org/schema/cache" 6 xmlns:context="http://www.springframework.org/schema/context" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 9 http://www.springframework.org/schema/cache 10 http://www.springframework.org/schema/cache/spring-cache-4.0.xsd 11 http://www.springframework.org/schema/context 12 http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 13 14 <context:component-scan 15 base-package="com.service"/> 16 17 <cache:annotation-driven cache-manager="cacheManager" /> 18 19 <-! EhCache configuration of CacheManager 20 ehcache.xml specify the location of the file by configLocation -> 21 <bean id="ehCacheManager" 22 class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" 23 p:configLocation="classpath:ehcache.xml" 24 p:shared="false" /> 25 <-! EhCache configuration is based on the Cache Manager 26 and EhCache of CacheManager injected into the Cache Manager Bean -> 27 <bean id="cacheManager" 28 class="org.springframework.cache.ehcache.EhCacheCacheManager" 29 percent: CacheManager-ref = "ehCacheManager"> 30 </bean> 31 32 </beans>
The following will @Cacheable example to demonstrate EhCache Spring-based cache usage. @Cacheable class or method for modification, if the modification of the class, then the class of all the methods are cached.
Class level cache
For example the following Bean class,
1 @Service("userService") 2 @Cacheable(value="users") 3 public class UserServiceImpl implements UserService { 4 5 @Override 6 public User getUsersByNameAndAge(String name, int age) { 7 System.out.println ( "executing getUsersByNameAndAge () .."); 8 return new User(name,age); 9 } 10 11 @Override 12 public User getAnotherUser(String name, int age) { 13 System.out.println ( "executing getAnotherUser () .."); 14 return new User(name,age); 15 } 16 }
Based cache class, all methods will cache class, after the cache, the program calls the class instance of any method, as long as the same parameters passed, Spring will not actually perform the method, but directly from the passed parameter to find the data in the cache!
Example is shown below using the cache data,
1 public static void test2() { 2 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 3 UserService us = ctx.getBean("userService", UserService.class); 4 User u1 = us.getUsersByNameAndAge("张三", 50); 5 // Since when calling userService second method, using the same parameters, then the real method will not be executed, 6 // Spring will look for data in parameters directly from the cache 7 User u2 = us.getAnotherUser ( "Joe Smith", 50); 8 System.out.println(u1==u2); 9 }
Output,
1 is performing getUsersByNameAndAge () .. 2 true
It can be seen above getAnotherUser () does not actually perform, since the same manner as the previous pass parameters into parameters, so Spring data directly from the cache.
The above comments @Cacheable Bean class value except the mandatory attributes, there are key, condition ,, unless properties are used to set the next three Spring storage policy for class-based cache, Spring's default to the method of the incoming parameters as key to cache search results.
Of course, we can also modify the key strategies, let Spring accordance with other standards, such as in accordance with the first argument is the same as the key, look for the results in the cache.
The above modified as follows Bean class,
1 @Service("userService") 2 @Cacheable(value="users", key="#name") 3 public class UserServiceImpl implements UserService { 4 5 @Override 6 public User getUsersByNameAndAge(String name, int age) {
Means that we pass the same name, Spring will not really perform the method. Only a different name when the method will really perform, such as the following,
1 public static void test2() { 2 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 3 UserService us = ctx.getBean("userService", UserService.class); 4 User u1 = us.getUsersByNameAndAge("张三", 50); After 5 // @Cacheable key parameter to the key = "# name", the following method may be performed. 6 User u2 = us.getAnotherUser ( "John Doe", 50); 7 System.out.println(u1==u2); 8 }
You can see this time getAnotherUser () method to be implemented, and
1 is performing getUsersByNameAndAge () .. 2 is performing getAnotherUser () .. 3 false
We can also set the condition attribute, for example,
1 @Service("userService") 2 @Cacheable(value="users", condition="#age<100") 3 public class UserServiceImpl implements UserService { 4 5 @Override 6 public User getUsersByNameAndAge(String name, int age) {
So, the following code, the two methods will not be cached, Spring execute every time real way to take the result,
1 public static void test2() { 2 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 3 UserService us = ctx.getBean("userService", UserService.class); 4 User u1 = us.getUsersByNameAndAge("张三", 500); 5 User u2 = us.getAnotherUser ( "John Doe", 500); 6 System.out.println(u1==u2); 7 }
Results of the,
1 is performing getUsersByNameAndAge () .. 2 is performing getAnotherUser () .. 3 false
Method-level cache
Method-level caching method will only work, the different ways you can set the unused buffer, such as follows,
1 @Service("userService") 2 public class UserServiceImpl implements UserService { 3 4 @Cacheable("users1") 5 @Override 6 public User getUsersByNameAndAge(String name, int age) { 7 System.out.println ( "executing getUsersByNameAndAge () .."); 8 return new User(name,age); 9 } 10 11 @Cacheable("users2") 12 @Override 13 public User getAnotherUser(String name, int age) { 14 System.out.println ( "executing getAnotherUser () .."); 15 return new User(name,age); 16 } 17 }
Use the following test code,
1 public static void test2() { 2 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 3 UserService us = ctx.getBean("userService", UserService.class); 4 // first execution method, the method will actually perform and cache 5 User u1 = us.getUsersByNameAndAge("张三", 500); 6 // Although the following method passing the same parameters, but since these two methods in different cache, cache data can not be used 7 User u2 = us.getAnotherUser ( "Joe Smith", 500); 8 System.out.println(u1==u2); 9 // As already cached, this will not really perform, direct use of cache 10 User u3 = us.getAnotherUser ( "Joe Smith", 500); 11 System.out.println(u3==u2); 12 }
Results of the,
1 is performing getUsersByNameAndAge () .. 2 is performing getAnotherUser () .. 3 false 4 true
Use @CacheEvict Clear Cache
The modified method can be used to clear the cache @CacheEvict using @CacheEvict can specify the following properties.
allEntries, whether to clear the entire cache
beforeInvocation: whether to clear the cache before execution method. The default method is only cleared after successful execution.
condiition and key, and @Cacheable the same meaning.
The following simple model with ah,
1 @Service("userService") 2 @Cacheable("users") 3 public class UserServiceImpl implements UserService { 4 5 @Override 6 public User getUsersByNameAndAge(String name, int age) { 7 System.out.println ( "executing getUsersByNameAndAge () .."); 8 return new User(name,age); 9 } 10 11 @Override 12 public User getAnotherUser(String name, int age) { 13 System.out.println ( "executing getAnotherUser () .."); 14 return new User(name,age); 15 } 16 // specified in terms of name, age parameter clear cache 17 @CacheEvict(value="users") 18 public void evictUser(String name, int age) { 19 System.out.println ( "- Emptying" + name + "," + age + "corresponding cache -"); 20 } 21 22 // Specify Clear user cache all cached data 23 @CacheEvict(value="users", allEntries=true) 24 public void evictAll() { 25 System.out.println ( "- emptying the entire cache -"); 26 } 27 }
Here is the test class,
1 public static void test2() { 2 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 3 UserService us = ctx.getBean("userService", UserService.class); 4 // buffers the two methods 5 User u1 = us.getUsersByNameAndAge("张三", 500); 6 User u2 = us.getAnotherUser ( "John Doe", 400); 7 // Call evictUser () method to clear the buffer specified data 8 us.evictUser ( "John Doe", 400); 9 // in front of John Doe cleared, the cache 400, the following method returns the data will be cached again 10 User u3 = us.getAnotherUser ( "John Doe", 400); 11 System.out.println(us == u3); //false 12 @ Joe Smith already cached data, 500, the following method will not re-executed, direct access to data in the cache 13 User u4 = us.getAnotherUser ( "Joe Smith", 500); 14 System.out.println (u1 == u4); // prints true 15 // clear the entire cache 16 us.evictAll(); 17 // Since the entire cache have been cleared, the following code will be re-executed 18 User u5 = us.getAnotherUser ( "Joe Smith", 500); 19 User u6 = us.getAnotherUser ( "John Doe", 400); 20 System.out.println (u1 == u5); // false output 21 System.out.println (u3 == u6); // false output 22 }
Results of the,
1 is performing getUsersByNameAndAge () .. 2 is performing getAnotherUser () .. 3 - emptying John Doe, 400 corresponding cache - 4 is performing getAnotherUser () .. 5 false 6 true 7-- is clear the entire cache - 8 is performing getAnotherUser () .. 9 is performing getAnotherUser () .. 10 false 11 false