Spring3.1新增了一种缓存机制,这种缓存机制与Spring容器无缝结合在一起,可以对容器中的任意bean或bean的方法增加缓存。Spring的缓存级别更高,可以在控制器组件或业务逻辑组件级别进行缓存,这样应用完全无需重复调用底层的DAO。
启动Spring缓存
xml中有一个cache命名空间专门用来配置缓存。启动缓存需要在xml中添加如下一行:
<cache:annotation-driven chache-manager="缓存管理器ID"/>
该元素指定Spring根据注解来启动bean级别或方法级别的缓存。此外还需要准对不同的缓存实现配置对应的缓存管理器。
EhCache缓存实现的配置
我们需要将Hibernate\lib\optiona\ehcache下的ehcache-core与slf4j-api两个jar包添加到项目中。前面是缓存核心包,后面是缓存工具的日志工具。为了使用ChCache,我们需要在应用的类加载路径下添加一个ehcache.xml文件:
<?xml version="1.0" encoding="gbk"?> <ehcache> <diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" maxElementsOnDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"/> <cache name="users" maxElementsInMemory="10000" eternal="false" overflowToDisk="true" timeToIdleSeconds="300" timeToLiveSeconds="600"/> </ehcache>
上面的文件配置了两个缓存区,一个是默认的,一个是users。由于这里使用EhCacheCacheManager作为缓存管理器,因此我们需要将这个对象配置在Spring容器中。但是EhCaheCacheManager底层需要一个net.sf.ehcache.CacheManager作为实际的缓存管理器。因此Spring提供了EhCacheManagerFactory
Bean这个工厂Bean,它实现了FactoryBean<CacheManager>接口。当把EhcacheManagerFactoryBean部署在容器中,实际上取用的是它的产品,也就是CacheManager对象。为了在容器中配置基于EhCache的缓存管理器,只要添加如下两段代码即可:
<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:ehcache.xml" p:shared="false"/> <bean id="cacheManager" class="prg.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager=ref="ehCacheManager"/>
首先我们配置了一个叫ehCacheManager的工厂类,它能够返回CacheManger对象。第二个才是为Spring缓存配置的基于EhCache的缓存管理器,它依赖于CacheManager,因此给它注入一个实例变量,也就是第一个工厂bean的索引。上述配置完成,我们就可以使用注解来驱动Spring将缓存数据存入指定缓存区了。
使用@Cacheable执行缓存
可以用@Cacheable来修饰类或者方法,以通知Spring框架在什么级别上使用缓存。如果是类级别,程序调用实例的任何方法都需要缓存。
类级别的缓存
如果类标注了缓存,那么对于其中任意方法,只要传入的参数相同,就回去调用缓存。通过调用缓存得到的两个实例,是相等的,同一个实例。
@Cacheable(value="users") public class UserServiceimpl implements UserService{ }
如果再增加一个key=”#name"属性,那么只要参数的name一样,就直接调用缓存,虽然其他参数并不一样,但是不管了!!!!!!!仍然是同一个对象实例。
condition属性可以指定只要condition表达式为true才会执行缓存,比如condition="#age<100",这样其他参数就会忽略了,只要age这一个小于100,那么就从缓存中调取,不再执行方法了。而unless则与此正好想反,只要unless后边的表达式为true,就不执行缓存。
方法级别的缓存
对方法进行标注,只要传入相同参数就从缓存掉。也支持上述其它属性
使用@CacheEvict清除缓存
被@CacheEvict标注的方法可以用来清除缓存。value属性用于指定清除哪个缓存区属性,allEntries指定是否清除整个缓存区。beforeInvocation指定是否在方法前清除缓存。默认的是在方法后的。condition指定一个SpEL表达式,只有当true才清除。key可以通过SpEL表达式显式地指定缓存的key。