spring cache
spring 缓存机制非常灵活,可以对spring 中的bean,bean中的方法进行缓存
spring缓存只是提供了缓存接口,具体的实现依赖于其它的缓存工具,如ehcache
使用缓存步骤
- 1.导入相应jar
spring-context-4.3.6.RELEASE.jar
spring-context-support-4.3.6.RELEASE.jar
spring-beans-4.3.6.RELEASE.jar
spring-aop-4.3.6.RELEASE.jar
spring-core-4.3.6.RELEASE.jar
spring-expression-4.3.6.RELEASE.jar
commons-logging-1.2.jar
如果使用ehcache,还需要导入
ehcache-core-2.5.0.jar
- 2.spring配置文件启用缓存,并配置缓存管理器
spring-cache.xml
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.0.xsd"> <context:component-scan base-package="com.basic.work.cache" /> <cache:annotation-driven cache-manager="cacheManager" /> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehCacheManager"> </bean> <bean id = "ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" > <property name="configLocation" value="classpath:cache.xml"></property> <property name="shared" value="false"></property> </bean> </beans>
- 3.cache缓存文件配置
cache.xml
<?xml version="1.0" encoding="UTF-8"?> <ehcache> <diskStore path="java.io.tmpdir" /> <!-- 配置默认的缓存区 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" maxElementsOnDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"/> <!-- 配置名为users的缓存区 --> <cache name="users" maxElementsInMemory="10000" eternal="false" overflowToDisk="true" timeToIdleSeconds="300" timeToLiveSeconds="600" /> </ehcache>
- 4.java使用缓存
package com.basic.work.cache; public interface UserService { User findNameById(String id,String name,int age); void findName(String id,String name,int age); void evict(String id,String name,int age); } package com.basic.work.cache; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; /** * @Cacheable 标注在类上:所有的方法都会被缓存,只要传入的参数相同,spring不会执行该方法,而是会 * 根据传入的参数去查找缓存中的数据 * key:缓存策略,key表明的字段如果相同,则去缓存中查找结果 * * @author chenzhubing * */ @Service("userService") @Cacheable(value="users",key="#name",condition="#age>10") public class UserServiceImpl implements UserService{ @Override public User findNameById(String id,String name,int age) { System.out.println("hello......"+id+" "+name); return new User(); } @Override public void findName(String id, String name, int age) { System.out.println("findName....."); } /** * 根据id,name ,age 清除缓存 */ @Override @CacheEvict(value="users",key="#name",condition="#age>10") public void evict(String id,String name,int age) { System.out.println("开始清除缓存....."); } } package com.basic.work.cache; import java.io.Serializable; public class User implements Serializable{ }
- 5.test
package com.basic.work.cache; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-cache.xml"); UserService us = (UserService)context.getBean("userService"); Object o1 = us.findNameById("11","a",9); us.findName("11", "a", 9); Object o2 = us.findNameById("1123","b",11); //age>10 才会查询缓存,因此o3 没有走缓存 Object o3 = us.findNameById("112","b",8); //name相同且age>10 因此o4 走缓存 Object o4 = us.findNameById("114","b",12); //清除name相同,age>10 的 缓存 us.evict("1123", "b", 11); //查看o5是否走缓存 Object o5 = us.findNameById("115","b",15); System.out.println(o1 == o2); System.out.println(o2 == o3); context.close(); } }
注解说明:
@Cacheable 可以作用在类和方法上面,作用在类上面的时候,表示对类中所有方法进行缓存。注解属性
value :对应cache.xml 缓存区中的名称
key:缓存策略,方法参数中,key标注的字段如果相同,则去缓存查询结果,而不会真正执行对应方法。
condition: 条件表达式,方法参数中满足该表达式则去缓存查询结果,而不会真正执行对应方法。
注意如果方法中有返回对象,则该对象必须实现序列化接口,这是因为返回对象会写入到本地缓存文件中 <diskStore path="java.io.tmpdir" />
@CacheEvict 可以作用在方法上,表示清除方法上的缓存,属性作用和 @Cacheable 类型
value:对应需要清除的缓存名称
key:清除缓存策略, 方法参数中, key标注的字段如果和缓存中相同,则清除缓存
condition:条件表达式,方法参数中满足该表达式则去清除缓存
allEntries:true表示清除整个缓存区,默认是false