做的项目暂告一个段落,想优化一下性能的,到网上查了一下搜得宝物ehcache。最终发现ehcache并非是想象的那样简单,现记录下过程,希望其他人少走弯路。
先获得的信息是spring如何配置ehcache,这是ehcache的第一种用法,利用spring的aop,定制两个interceptor,一为执行方法时,将查询结果放入cache,如果在cache中已经存在,则直接从cache中取出。主要针对查询动作(以class名+方法名+参数名作为key);一为方法执行后,在诸如update,delete,create的动作后删除相关cache内的内容。通过spring的applicationContext配置后即可使用,网上有很多的例子,单独架设起来并不困难,也可以顺利跑通。但当我想整合到项目中时却发现tomcat报错,总是说sesstionFactory无法初始化,无法初始化的原因是com.mchange.v2.c3p0.ComboPooledDataSource 不能被cast成serializable类型,看了一下出错的地方,是第一个interceptor方法里面有一句element = new Element(cacheKey, (Serializable) result);。网上也没有什么解释,看来是没有什么人这样用。回头想一下也确实是,在spring这一层加上cache能缓存什么内容呢?至少目前的这个障碍还无法逾越,只好继续去网上搜索。
接下来看到的是hibernate如何配置ehcache,这个配置不是很复杂,主要是在声明hibernate的地方,加上如下三句话,告诉spring,hibernate需要用ehcache作为二级缓存:
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
然后,在对应的xxx.hbm.xml里,class之后,id之前注明cache读写的类型,
<cache usage="nonstrict-read-write"></cache>
最后在对应的dao中设定getHibernateTemplate().setCacheQuery(true), 这样就可以了。
最后一种是在查询过程中发现的副产品,对网页的cache,这里主要是在web.xml中进行配置,设定好filter和filtermapping,如下:
<filter>
<filter-name>indexCacheFilter</filter-name>
<filter-class>
net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter
</filter-class>
<init-param>
<param-name>cacheName</param-name>
<param-value>MyCache</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>indexCacheFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
其中MyCache是ehcache.xml中cache的名称,可以自己定制。另外还有Gzip的配置,对压缩js,css比较适合。
<filter>
<filter-name>GzipFilter</filter-name>
<filter-class>net.sf.ehcache.constructs.web.filter.GzipFilter</filter-class>
<init-param>
<param-name>exceptionsToLogDifferently</param-name>
<param-value>net.sf.ehcache.CacheException, java.lang.NullPointerException
</param-value>
</init-param>
<init-param>
<param-name>exceptionsToLogDifferentlyLevel</param-name>
<param-value>fatal</param-value>
</init-param>
<init-param>
<param-name>suppressStackTraces</param-name>
<param-value>false</param-value>
</init-param>
</filter>
另外,在查询过程中,还发现ehcache有不同种类的cache,class cache, query cache以及collection cache,另外对cache如何合理配置的问题需要再花时间研究。
SSH的框架确实灵活,有时也会因为选择太多而困惑。