8 -- 深入使用Spring -- 5...1 启用Spring缓存
8.5.1 启用Spring缓存
Spring配置文件专门为缓存提供了一个cache:命名空间,为了启用Spring缓存,需要在配置文件中导入cache:命名空间。
导入cache:命名空间之后,启用Spring缓存还要两步:
① 在Spring配置文件中添加<cache:annotation-driven cache-manager="缓存管理器ID"/>,该元素指定Spring根据注解来启用Bean级别或方法级别的缓存。
② 针对不同的缓存实现配置对应的缓存管理器。
第1步使用<cache:annotation-driven.../>元素时可通过cache-manager显式指定容器中缓存管理器的ID;该属性的默认值为cacheManager ------ 也就是说,如果将容器中缓存管理器的ID设为cacheManager,则可省略<cache:annotation-driven.../>的cache-manager属性。
第2步由于Spring底层可使用大部分主流的Java缓存工具,而不同的缓存工具所需的配置也不同,因此略微有点麻烦。
以Spring内置的缓存实现和EhCache为例来介绍Spring缓存的配置:
1.Spring 内置缓存实现的配置
Spring内置的缓存实现只是一种内存中的缓存,并非真正的缓存实现,因此通常只能用于简单的测试环境,不建议在实际项目中使用Spring内置的缓存实现。
Spring内置的缓存实现使用SimpleCacheManager作为缓存管理器,使用SimpleCacheManager配置缓存非常简单,直接在Spring容器中配置该Bean,然后通过<property.../>驱动该缓存管理器执行setCaches()方法来设置缓存区即可。
SimpleCacheManager是一种内存中的缓存区,底层直接使用了JDK的ConcurrentMap来实现缓存,SimpleCacheManager使用了ConcurrentMapCacheFactoryBean作为缓存区,每个ConcurrentMapCacheFactoryBean配置一个缓存区。
配置Spring内置缓存的缓存管理器DEMO:
<?xml version="1.0" encoding="UTF-8"?> <!-- Spring 配置文件的根元素,使用Spring-beans-4.0.xsd语义约束 --> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:P="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 使用SimpleCacheManager配置Spring内置的缓存管理器 --> <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <!-- 配置缓存区 --> <property name="caches"> <set> <!-- 使用ConcurrentMapCacheFactoryBean配置缓存区 --> <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"> <!-- 为缓存区指定名字 --> <property name="name" value="default"/> </bean> <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"> <!-- 为缓存区指定名字 --> <property name="name" value="users"/> </bean> </set> </property> </bean> </beans>
配置文件使用SimpleCacheManager配置了Spring内置的缓存管理器,并为该缓存管理器配置了两个缓存区:default和users ------ 这些缓存区的名字很重要,因为后面使用注解驱动缓存时需要根据缓存区的名字来将缓存放入指定缓存区内。
提示:
在实际的应用中,开发者可以根据自己的需要,配置更多的缓存区,一般来说,应用有多少个组件需要缓存,程序就应该配置多少个缓存区。
2.EhCache缓存实现的配置
在配置EhCache缓存实现之前,首先需要将EhCache缓存的JAR包添加到项目的类加载路径中。
ehcache-core-x.x.x.jar : 是EhCache的核心JAR包;
slf4j-api-x.x.x.jar : 是该缓存工具所使用的日志工具;
为了使用EhCache,同样需要在应用的类加载路径下添加一个ehcache.xml配置文件。
ehcache.xml :
<?xml version="1.0" encoding="UTF-8"?> <ehcache> <diskStore path="java.io.tmpdir" /> <!-- 配置默认的缓存区 --> <defaultCache maxElementsInMemory="10000" eternaml="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>
其中第一个用于配置匿名的、默认的缓存区,第二个才是配置了名为users的缓存区。如果需要,完全可以将<cache.../>元素复制多个,用于配置多个有名字的缓存区。这些缓存区的名字同样很重要,后面使用注解驱动缓存时需要根据缓存区的名字来将缓存数据放入指定缓存区内。
Spring使用EhCacheCacheManager作为EhCache缓存实现的缓存管理器,因此只要该对象配置在Spring容器中,它就可作为缓存管理器使用,但EhCacheCacheManager底层需要依赖一个net.sf.ehcache.CacheManager作为实际的缓存管理器。
为了将net.sf.ehcache.CacheManager纳入Spring容器的管理之下,Spring提供了EhCacheManagerFactoryBean工厂Bean,该工厂Bean实现了FactoryBean<CacheManager>接口。当程序把EhCacheManagerFactoryBean部署在Spring容器中,并通过Spring容器请求获取工厂Bean时,实际返回的是它的产品 ------ 也就是CacheManager对象。因此,为了在Spring配置文件中配置基于EhCache的缓存管理器,只要增加如下两段配置即可:
<?xml version="1.0" encoding="UTF-8"?> <!-- Spring 配置文件的根元素,使用Spring-beans-4.0.xsd语义约束 --> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:P="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置EhCache的CacheManager通过configLocation指定ehcache.xml文件的位置 --> <bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="classpath:ehcache.xml"/> <property name="shared" value="false"/> </bean> <!-- 配置基于EhCache的缓存管理器 --> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> <property name="cacheManager" ref="ehCacheManager"/> </bean> </beans>
Spring配置文件中,第一个Bean是一个工厂Bean,它用于配置EhCache的CacheManager;第二个Bean才是为Spring缓存配置的基于EhCache的缓存管理器,该缓存管理器需要依赖于CacheManager,因此程序将第一个Bean注入到第二个Bean中
配置好人一种缓存管理器之后,接下来就可使用注解来驱动Spring将缓存数据存入指定缓存区了。