Ehcache是使用Java编写的缓存框架,比较常用的是,整合在Hibernate和MyBatis这种关系型数据库持久框架。
不过现在用NoSQL也比较盛行,要应用Ehcache,整合起来就没法按照那两个持久框架的方式。
比较通用的方式就是用Spring框架中的Cache功能,配合Cache相关注解来使用,这样不管数据库是关系型的还是NoSQL都是通用。
Ehcache配置
不管和哪个框架整合,ehcache的配置方式都是固定,只需配置ehcache.xml文件,一般默认放在classpath根目录下
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"> <diskStore path="D:/onda" /> <defaultCache maxElementsInMemory="3000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="3600" overflowToDisk="true" diskPersistent="false" diskExpiryThreadIntervalSeconds="100" memoryStoreEvictionPolicy="LRU" /> <cache name="one" maxElementsInMemory="3000" eternal="false" overflowToDisk="true" timeToIdleSeconds="3600" timeToLiveSeconds="3600" memoryStoreEvictionPolicy="LFU" /> </ehcache>
参考文档
http://www.ehcache.org/ehcache.xml
与Spring整合应用Spring Cache注解
Spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.2.xsd"> <cache:annotation-driven cache-manager="cacheManager" /> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehcache" /> <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:ehcache.xml" p:shared="true" /> </beans>
注:<cache:annotation-driven cache-manager="cacheManager" />加这个标签需要在xmlns引入cache和xsi:schemaLocation指定spring-cache-4.2.xsd文件
Java代码
@Service public class UserService { @Autowired private UserDao userDao; @Cacheable(value="one") public List<User> getUsers() { return userDao.getUsers(); } }
Java示例代码中,在方法上加@Cacheable注解,说明这个方法是可以被缓存的
当程序调用此方法时,会先到缓存里查找是否存在,如果存在则返回缓存里的数据,如果不存在则执行这个方法获取数据,并把数据库放入缓存中。
@Cacheable注解里,有好几个参数,比如value是指定缓存的名称
Spring配置问题
用Cache注解方式,可能会碰到Spring配置问题。
可能在项目中应用了SpringMVC框架,因为配置文件没指定好,导致缓存操作失效
应用SpringMVC,在web.xml配置如下信息
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring-core.xml</param-value> </context-param> <servlet> <servlet-name>springMvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
ContextLoaderListener和DispatcherServlet这两个类分别是两个不同的ApplicationContext
如果以下信息是在spring-mvc.xml这个文件里配置
<context:component-scan base-package="com.zhang" /> <mvc:annotation-driven />
<cache:annotation-driven cache-manager="cacheManager" />配置在spring-core.xml,就算在代码里加了@Cache注解,也是无效的
正确方式,是把context:component-scan和cache:annotation-driven配置在同一个xml文件里
具体的原因,可以搜索ContextLoaderListener和DispatcherServlet这两个类加载bean的不同