Web项目数据缓存--SpringCache与Ehcache实现

需求:

    1.系统需要加一个实时的报警列表,就是说如果用户不处理报警就一直弹出右下角提示框.

思路:

    1.这个需求在数据交互方面实现起来没有什么难点,问题主要在实时性;
    2.当时想到了两个解决方案,第一个是类似聊天室功能实现的HTTP长连接,第二个就是在后台做数据的缓存,从减少数据库的交互,来减轻频繁造成负担(ps:只是减轻.客户端和服务端的ajax还是一直在跑);
    3.后来,选择了缓存的方式实现.因为,第一Spring已经帮我把缓存中很多重要的步骤完成了(我只需要在需要缓存的数据函数上加个注解和配置就可以),第二长连接会一直占有服务器的系统资源(特别是内存).对于我们这种服务器硬件的压力会有隐患(并不是不行,而是我们的服务器采购的时候一般不会考虑这方面的性能).
环境:
    1.spring-context.jar
    2.spring-context-support.jar

过程:

    1.定义Ehcache缓存配置文件用于指定缓存对象的一些属性.比如失效时间等,其中name是spring的beanId.其他属性在备注中有阐述.
    
<ehcache>
	<!-- <diskStore path="d:\\temp\\cache" /> (企业版支持)-->
	<!-- default cache -->
	<defaultCache maxElementsInMemory="100000" eternal="false"
		 timeToLiveSeconds="36000" overflowToDisk="false" />
	<!-- 缓存10个小时 -->
	<cache name="queryEquWaring" maxElementsInMemory="100000" eternal="false"
		 timeToLiveSeconds="36000" overflowToDisk="false"/>
</ehcache>

<!-- 
defaultCache这些配置只会对在程序中通过CacheManager的addCache(String cacheName)方法添加的Cache起作用.
 -->

<!-- 
cache元素中可以指定的属性也有很多,但只有一个是必须的。那就是name属性。
       name:指定cache的名称。
       maxEntriesLocalDisk:指定允许在硬盘上存放元素的最大数量,0表示不限制。这个属性我们也可以在运行期通过CacheConfiguration来更改。
       maxEntriesLocalHeap:指定允许在内存中存放元素的最大数量,0表示不限制。这个属性也可以在运行期动态修改。
       maxEntriesInCache:指定缓存中允许存放元素的最大数量。这个属性也可以在运行期动态修改。但是这个属性只对Terracotta分布式缓存有用。
       maxBytesLocalDisk:指定当前缓存能够使用的硬盘的最大字节数,其值可以是数字加单位,单位可以是K、M或者G,不区分大小写,如:30G。当在CacheManager级别指定了该属性后,Cache级别也可以用百分比来表示,如:60%,表示最多使用CacheManager级别指定硬盘容量的60%。该属性也可以在运行期指定。当指定了该属性后会隐式的使当前Cache的overflowToDisk为true。
       maxBytesLocalHeap:指定当前缓存能够使用的堆内存的最大字节数,其值的设置规则跟maxBytesLocalDisk是一样的。
       maxBytesLocalOffHeap:指定当前Cache允许使用的非堆内存的最大字节数。当指定了该属性后,会使当前Cache的overflowToOffHeap的值变为true,如果我们需要关闭overflowToOffHeap,那么我们需要显示的指定overflowToOffHeap的值为false。
       (企业版支持)overflowToDisk:boolean类型,默认为false。当内存里面的缓存已经达到预设的上限时是否允许将按驱除策略驱除的元素保存在硬盘上,默认是LRU(最近最少使用)。当指定为false的时候表示缓存信息不会保存到磁盘上,只会保存在内存中。该属性现在已经废弃,推荐使用cache元素的子元素persistence来代替,如:<persistence strategy=”localTempSwap”/>。
       diskSpoolBufferSizeMB:当往磁盘上写入缓存信息时缓冲区的大小,单位是MB,默认是30。
       overflowToOffHeap:boolean类型,默认为false。表示是否允许Cache使用非堆内存进行存储,非堆内存是不受Java GC影响的。该属性只对企业版Ehcache有用。
       copyOnRead:当指定该属性为true时,我们在从Cache中读数据时取到的是Cache中对应元素的一个copy副本,而不是对应的一个引用。默认为false。
       copyOnWrite:当指定该属性为true时,我们在往Cache中写入数据时用的是原对象的一个copy副本,而不是对应的一个引用。默认为false。
       timeToIdleSeconds:单位是秒,表示一个元素所允许闲置的最大时间,也就是说一个元素在不被请求的情况下允许在缓存中待的最大时间。默认是0,表示不限制。
       timeToLiveSeconds:单位是秒,表示无论一个元素闲置与否,其允许在Cache中存在的最大时间。默认是0,表示不限制。
       eternal:boolean类型,表示是否永恒,默认为false。如果设为true,将忽略timeToIdleSeconds和timeToLiveSeconds,Cache内的元素永远都不会过期,也就不会因为元素的过期而被清除了。
       diskExpiryThreadIntervalSeconds :单位是秒,表示多久检查元素是否过期的线程多久运行一次,默认是120秒。
       clearOnFlush:boolean类型。表示在调用Cache的flush方法时是否要清空MemoryStore。默认为true。
       memoryStoreEvictionPolicy:当内存里面的元素数量或大小达到指定的限制后将采用的驱除策略。默认是LRU(最近最少使用),可选值还有LFU(最不常使用)和FIFO(先进先出)。
 -->
 
    2.在spring-cache.xml文件中,配置缓存管理bean.
<?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:bean="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.xsd">

	<!-- spring 注解缓存开启 -->
	<cache:annotation-driven />

	<!--spring cache 采用 Ehcache实现 -->
	<cache:annotation-driven cache-manager="cacheManager" />

	<!-- cacheManagerFactory为由Spring生成的ehcache的cacheManager -->
	<bean id="cacheManagerFactory"
		class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
		<property name="configLocation" value="classpath:conf/ehcache.xml" />
	</bean>

	<!--Spring的cacheManager使用Ehcache的cacheManager -->
	<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
		<property name="cacheManager" ref="cacheManagerFactory" />
	</bean>
	<!-- 报警列表的缓存 -->
	<bean id="queryEquWaring" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
		<property name="cacheName" value="queryEquWaring" />
		<property name="cacheManager" ref="cacheManagerFactory" />
	</bean>

    <!-- 自定义的cache key生成器 -->
    <bean id="customKeyGenerator" class="ths.jdp.core.cache.CustomKeyGenerator"/>
</beans>
cacheManagerFactory
    3.在spring.xml中引入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:bean="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.xsd">


	<import resource="spring-core.xml" />
	<import resource="spring-cache.xml" />
	<import resource="datasource.xml" />
	<import resource="spring-db.xml" />
	<import resource="spring-mybatis.xml" />
	<!-- 
	<import resource="spring-job.xml" />
 	//-->
</beans>
 
    4.在servise方法上添加注解,将方法的返回值加入缓存池
@Service
public class EquWaringService extends BaseService {
	private final String sqlPackage = "ths.project.portal.equipment.mapper.equWarningMapper";

	@Cacheable(value="queryEquWaring",keyGenerator="customKeyGenerator" condition="1==1")
	public List<Map<String, Object>> queryEquWarning(Map<String, Object> form) {
		return dao.list(form, sqlPackage+".queryEquWarning");
	}
	@CacheEvict(value="queryEquWaring",allEntries=true,beforeInvocation=true)
	public int updateEquWaring(Map<String, Object> form){
		return dao.update(form, sqlPackage+".updateEquWaring");
	}	
}
Cacheable

原理:

    --springCache基于spring AOP 通过动态生成的 proxy 代理机制来对方法的调用进行切面实现缓存逻辑代码的嵌入--
    1.在spring-cache.xml文件中开启springCache缓存机制;
    2.在spring-cache.xml文件中设置缓存的实现类为org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
    3.将我的value为queryEquWaring的缓存对象交给cacheManagerFactory来管理;
    4.在service中通过@Cacheable标签来定义方法,每次在外部类调用的时候,springCache会先去缓存池中取数据,如果没有才会调用方法返回结果,并将返回值加载到缓存池中;
    5.我们也可以通过使用@CacheEvict标签来清空缓存;

总结:

    1.PS:通过@Cacheable注解的缓存方法,如果在缓存池中找到数据.Spring就不会再调用的这个方法了.而是直接返回缓存中的数据.如果,我还需要执行这个方法那可以使用@ CachePut来注解方法;
    2.PS:condition参数用来指定当前操作的条件,返回值应该是一个boolean.支持spEL表达式,CacheEvict中beforeInvocation参数是用于指定清空缓存的操作是在方法执行前,还是后.默认值是在后,我觉得还是在后好些,因为在后的话.这个方法报错后.缓存是不清空的.当然看需求.
    3.SpringCache只支持在类外部的方法调用才会保存和清空缓存,原因就是proxy会在this关键字下失效.

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

 
 
 
 

转载于:https://www.cnblogs.com/CoderGuokai/p/7886080.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值