缓存-ehcach使用以及simplepagecache的使用

45 篇文章 1 订阅

         一般在项目中都要用到缓存,比如hibernate一级、二级缓存,对象缓存,方法缓存,页面缓存,浏览器缓存等等。这里主要说下我在上个公司用到的使用ehcach方法缓存(分布式缓存)和simplepagecache页面缓存(需要改变tomcat启动编码),使用simplepagecache的目的是由于实现能够随时删除指定的页面缓存以及查看页面的访问次数。

        下面首先说下方法缓存,看ehcache.xml文件。

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
	<!--
		maxElementsInMemory为缓存对象的最大数目,
		eternal设置是否永远不过期,timeToIdleSeconds对象处于空闲状态的最多秒数,timeToLiveSeconds对象处于缓存状态的最多秒数
	-->
	<diskStore path="java.io.tmpdir" />
	<cacheManagerEventListenerFactory class="" properties=""/>
	 <cacheManagerPeerProviderFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
            properties="peerDiscovery=automatic,
                        multicastGroupAddress=230.0.0.1,
                        multicastGroupPort=4446"/>
	<cacheManagerPeerListenerFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"/>
            
	<defaultCache maxElementsInMemory="10000" 
				eternal="false"
				timeToIdleSeconds="60" 
				timeToLiveSeconds="60" 
				overflowToDisk="true" />

	<cache name="org.hibernate.cache.StandardQueryCache"
		maxElementsInMemory="5000" 
		eternal="false" 
		timeToIdleSeconds="180"
		timeToLiveSeconds="180" 
		overflowToDisk="true" />
	<cache name="org.hibernate.cache.UpdateTimestampsCache"
		maxElementsInMemory="10000" 
		eternal="true" 
		overflowToDisk="true" />

	
	<!--service层 方法缓存的数据过期策略 -->
	<cache name="myCache"
		maxElementsInMemory="10000"
		eternal="false"
		overflowToDisk="true"
		timeToIdleSeconds="1"
		timeToLiveSeconds="1"
		memoryStoreEvictionPolicy="LFU" />
		
	<!--系统自定义 缓存的数据过期策略 永不过期 -->
	<cache name="customerLongCache"
		maxElementsInMemory="10000"
		eternal="true"
		overflowToDisk="true"
		timeToIdleSeconds="300000000"
		timeToLiveSeconds="600000000"
		memoryStoreEvictionPolicy="LFU" />
		
			<!--设置user类的缓存的数据过期策略 -->
	<cache name="net.b2c.u.model.UserU" 
		maxElementsInMemory="1000" 
		eternal="false"
		timeToIdleSeconds="2" 
		timeToLiveSeconds="2" 
		overflowToDisk="false"
		memoryStoreEvictionPolicy="LFU" />
		
		
		
		<!--页面缓存策略 -->
		<cache name="SimplePageCachingFilter" 
		maxElementsInMemory="10000" 
		eternal="false"
		overflowToDisk="false" 
		timeToIdleSeconds="43200" 
		timeToLiveSeconds="43200"
		memoryStoreEvictionPolicy="LFU">
		<cacheEventListenerFactory
                class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
        <bootstrapCacheLoaderFactory
                class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"/>
		</cache>

	<!--主页缓存策略 --> <!-- 12小时 赞用于调用亿起发数据缓存策略-->
	<cache name="yqfProductCache"
		maxElementsInMemory="10000"
		eternal="false"
		overflowToDisk="true"
		timeToIdleSeconds="43200"  
		timeToLiveSeconds="43200"
		memoryStoreEvictionPolicy="LFU" >
		<cacheEventListenerFactory
                class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
        <bootstrapCacheLoaderFactory
                class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"/>
		</cache>
	
	<cache name="yqfProductURLCache"
		maxElementsInMemory="10000"
		eternal="false"
		overflowToDisk="true"
		timeToIdleSeconds="43200"  
		timeToLiveSeconds="43200"
		memoryStoreEvictionPolicy="LFU" >
		<cacheEventListenerFactory
                class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
        <bootstrapCacheLoaderFactory
                class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"/>
		</cache>
	
	<cache name="yqfTptURLCache"
		maxElementsInMemory="10000"
		eternal="false"
		overflowToDisk="true"
		timeToIdleSeconds="43200"  
		timeToLiveSeconds="43200"
		memoryStoreEvictionPolicy="LFU">
		<cacheEventListenerFactory
                class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
        <bootstrapCacheLoaderFactory
                class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"/>
		</cache>
		
		<cache name="shopcache"
		maxElementsInMemory="300"
		eternal="false"
		overflowToDisk="true"
		timeToIdleSeconds="43200"  
		timeToLiveSeconds="43200"
		memoryStoreEvictionPolicy="LFU">
		<cacheEventListenerFactory
                class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
        <bootstrapCacheLoaderFactory
                class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"/>
		</cache>
		
</ehcache>

 


具体的每个配置意义我就不再详细说明,可以在网上查找,主要说下这里的每个cache,可以当成一个存放在内存中的map数据结构,有key,有value。

关键代码如下:

package net.b2c.yqf.util;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;


public class CacheUtil {
	private static Cache cache =null;
	private static Cache cacheUrl = null;
	private static Cache chacheTuanUrl = null;
	static {
		// 使用默认配置文件创建CacheManager
		CacheManager manager = CacheManager.create();
		 cache = manager.getCache("yqfProductCache");
		 cacheUrl = manager.getCache("yqfProductURLCache");
		 chacheTuanUrl = manager.getCache("yqfTptURLCache");
		 
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		//保存数据到cache中
		Element element = new Element("key1", "value1");
		cache.put(element);
		
		
		//从cache中取回元素
		Element element2 =  getCache().get("key1");
		element2.getValue();
		
		//从Cache中移除一个元素
		//	cache.remove("key");
		
		System.out.println(element2.getValue());

	}
	public static Cache getCache() {
		return cache;
	}
	public static Cache getCacheUrl() {
		return cacheUrl;
	}
	public static Cache getChacheTuanUrl() {
		return chacheTuanUrl;
	}

	
}
	/**
	 * 全部团购子目录
	 */
	public static List<TuanCategory> getCacheTuanGouCotegoryAll(){
		List<TuanCategory> list = new ArrayList<TuanCategory>();
		String mlKey = "tuangouzimuluall";
		Cache cache = CacheUtil.getCache();
		Element element = null;
		synchronized (mlKey) {
			element = cache.get(mlKey);
			if(element!=null){
				list = (List<TuanCategory>)element.getValue();
				if(list == null){
					List<TuanCategory> listResult = YQF. getTuanGouCotegory();
					if(listResult!=null){
						for (TuanCategory tuanCategory : listResult) {
							if(!tuanCategory.getIsParent()){
								list.add(tuanCategory);
							}
						}
						Element elem = new Element(mlKey,list);
						cache.put(elem);
					}
				}
			}else{
				List<TuanCategory> listResult = YQF. getTuanGouCotegory();
				if(listResult!=null){
					for (TuanCategory tuanCategory : listResult) {
						if(!tuanCategory.getIsParent()){
							list.add(tuanCategory);
						}
					}
					Element elem = new Element(mlKey,list);
					cache.put(elem);
				}
			}
		}
		return list;
	}


相信大家一定都能看得懂上面的代码。

拦截指定方法的cache

package net.b2c.u.interceptor;

import java.io.Serializable;

import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;


import org.aspectj.lang.ProceedingJoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class CacheIntercept {
	private Logger logger= LoggerFactory.getLogger(getClass());
	private Cache cache;
	

	public Cache getCache() {
		return cache;
	}

	public void setCache(Cache cache) {
		this.cache = cache;
	}
	
	private String getCacheKey(String targetName, String methodName,
			Object[] arguments) {
		StringBuffer sb = new StringBuffer();
		sb.append(targetName).append(".").append(methodName);
		if ((arguments != null) && (arguments.length != 0)) {
			for (int i = 0; i < arguments.length; i++) {
				sb.append(".").append(arguments[i].toString());
			}
		}
		return sb.toString();
	}
	
	public Object myCache(ProceedingJoinPoint pjp) throws Throwable
	{
	//	System.out.println("maxSec:"+getMaxSecond());
		
		String className = pjp.getTarget().getClass().getName();
		String methodName=pjp.getSignature().getName();
		
			
		Object[] args=	pjp.getArgs();
		
		
		String cacheKey = getCacheKey(className, methodName, args);
		logger.info("mycache_query_cacheKey:"+cacheKey);
		Element element = null;
		Object result=null;
		synchronized (cacheKey) {
			element = cache.get(cacheKey);
			if (element == null) {
				logger.info("mycache_cacheKey_not_exist:"+cacheKey);
				
				result = pjp.proceed(args);
				logger.info("mycache_cache_result:"+result);
				element = new Element(cacheKey, (Serializable) result);
				cache.put(element);
			}else{
				logger.info("mycache_cacheKey_exist:"+cacheKey);
			}
		}
		
		
		
		return result;
	}
	
	
}

	<!-- 缓存配置 拦截器 -->
	<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"></bean>
		<bean id="myCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
			<property name="cacheManager" ref="cacheManager" />
			<property name="cacheName">
			<value>myCache</value>
			</property>
		</bean>
	<bean id="cacheInterceptor" class="net.b2c.u.interceptor.CacheIntercept">
		<property name="cache">
			<ref local="myCache"/>			
		</property>		
	</bean>

	 <aop:config>
		<aop:pointcut id="mypointcut"
			expression="execution(public * net.b2c.u.service..*.*(..))" />

		<aop:aspect id="cacheAspect" ref="cacheInterceptor">
			
			<aop:around method="myCache" pointcut-ref="mypointcut"/>
		</aop:aspect>
	</aop:config> 


下面说说simplepagecache,先看效果

配置:

package net.b2c.u.interceptor;

import java.util.Enumeration;

import javax.servlet.FilterChain;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import net.sf.ehcache.CacheException;

import net.sf.ehcache.constructs.blocking.LockTimeoutException;

import net.sf.ehcache.constructs.web.AlreadyCommittedException;

import net.sf.ehcache.constructs.web.AlreadyGzippedException;

import net.sf.ehcache.constructs.web.filter.FilterNonReentrantException;

import net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter;

import org.apache.commons.lang.StringUtils;

import org.apache.log4j.Logger;

/**
 * 
 * 页面缓存过滤器
 */

public class PageEhCacheFilter extends SimplePageCachingFilter {

	private final static Logger log = Logger.getLogger(PageEhCacheFilter.class);

	private final static String FILTER_URL_PATTERNS = "patterns";
	private final static String NO="callback";

	private static String[] cacheURLs;

	private void init() throws CacheException {

		String patterns = filterConfig.getInitParameter(FILTER_URL_PATTERNS);

		cacheURLs = StringUtils.split(patterns, ",");
		
	}

	@Override
	protected void doFilter(final HttpServletRequest request,

	final HttpServletResponse response, final FilterChain chain)

	throws AlreadyGzippedException, AlreadyCommittedException,

	FilterNonReentrantException, LockTimeoutException, Exception {

		if (cacheURLs == null) {
            init();
        }
		
        
        String url = request.getRequestURI();
//       log.debug("url:"+url);
        boolean flag = false;
        if (cacheURLs != null && cacheURLs.length > 0) {
            for (String cacheURL : cacheURLs) {
                if (url.equals(cacheURL.trim())) {
                    flag = true;
                    break;
                }
            }
        }
        // 如果包含我们要缓存的url 就缓存该页面,否则执行正常的页面转向
        if (flag) {
            String query = request.getQueryString();
            if (query != null) {            	
            	
            	if(query.contains(NO))
            	{
            		chain.doFilter(request, response);
            		 return;
            	}
            	
            	
                query = "?" + query;
            }
            log.info("当前请求被缓存:" + url + query);
            super.doFilter(request, response, chain);
        } else {
            chain.doFilter(request, response);
        }

	}

	@SuppressWarnings("unchecked")
	private boolean headerContains(final HttpServletRequest request,
			final String header, final String value) {

		logRequestHeaders(request);

		final Enumeration accepted = request.getHeaders(header);

		while (accepted.hasMoreElements()) {

			final String headerValue = (String) accepted.nextElement();

			if (headerValue.indexOf(value) != -1) {

				return true;

			}

		}

		return false;

	}

	@Override
	protected boolean acceptsGzipEncoding(HttpServletRequest request) {

		boolean ie6 = headerContains(request, "User-Agent", "MSIE 6.0");

		boolean ie7 = headerContains(request, "User-Agent", "MSIE 7.0");
		
		return acceptsEncoding(request, "gzip") || ie6 || ie7;

	}
	
	@Override
	protected String calculateKey(HttpServletRequest httpRequest) {
		 StringBuffer stringBuffer = new StringBuffer();
		 String uri=httpRequest.getRequestURI();
		 String parram=httpRequest.getQueryString();
		 if(null == parram )parram="";
	        stringBuffer.append(uri).append(parram);
	        String key = stringBuffer.toString();
	        return key;
	}
	
	

}


 

<filter>
    <filter-name>SimplePageCachingFilter</filter-name>
    <filter-class>net.b2c.u.interceptor.PageEhCacheFilter</filter-class>
    <init-param>
      <param-name>patterns</param-name>
      <param-value></param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>SimplePageCachingFilter</filter-name>
    <url-pattern>/</url-pattern>
    <url-pattern>*.jsp</url-pattern>
    <url-pattern>*.action</url-pattern>
  </filter-mapping>


 

<%@page import="java.util.Date"%>
<%@page import="net.sf.ehcache.Element"%>
<%@page import="net.sf.ehcache.constructs.blocking.BlockingCache"%>
<%@page import="net.sf.ehcache.CacheManager"%>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
       <%
	String ctxpath = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>页面缓存</title>
	<link rel="stylesheet" type="text/css" href="../../css/demo_page.css" />
	<link rel="stylesheet" type="text/css" href="../../css/demo_table.css" />
		<script type="text/javascript" language="javascript" src="../../js/jquery-1.7.1.js"></script>
		<script type="text/javascript" src="../../js/jquery.form.js"></script>
<style type="text/css">
	.btr{border:1px solid #D9E7F8;border-collapse:collapse;}
</style>		
		
</head>

<body id="dt_example" class="ex_highlight_row">
	<br>
<%
	CacheManager manager = CacheManager.create();
	BlockingCache cache = new BlockingCache(manager.getEhcache("SimplePageCachingFilter"));

	if(cache.getSize()>0){
%>
	<table width="100%" align="center">
		<tr><td align="center"><font size="4px">所有静态化页面</font></td></tr>
	</table>
	<br>
	<table width="90%" align="center">
		<tr>
			<td width="20%">缓存中对象个数:<%=cache.getSize() %></td>
			<td width="80%">缓存读取的命中次数:<%=cache.getStatistics().getCacheHits() %></td>
		</tr>
		<tr>
			<td >缓存对象占用内存的大小:<%=cache.getMemoryStoreSize() %></td>
			<td>缓存读取的错失次数:<%=cache.getStatistics().getCacheMisses() %></td>
		</tr>
	</table>
	<br>
	<table width="90%" class="btr" align="center">
		<tr  class="btr">
			<th width="10%"  class="btr">序号</th>
			<th width="30%"  class="btr">缓存页面</th>
			<th width="10%"  class="btr">访问次数</th>
			<th width="15%"  class="btr">缓存时间</th>
			<th width="15%"  class="btr">过期时间</th>
			<th width="20%"  class="btr">操作</th>
		</tr>
	<%
		int i = 0;
		for(Object obj:cache.getKeysWithExpiryCheck()){
			i++;
			Element el=cache.getQuiet(obj);
	%>	
		<tr  class="btr">
			<td  class="btr" align="center"><%=i %></td>
			<td  class="btr" align="center"><%=obj %></td>
			<td  class="btr" align="center"><%=el.getHitCount() %></td>
			<td  class="btr" align="center"><%=new Date(el.getCreationTime()).toLocaleString() %></td>
			<td  class="btr" align="center"><%=new Date(el.getExpirationTime()).toLocaleString() %></td>
			<td  class="btr" align="center">
				<input type="button" value="清 楚 缓 存" οnclick="clearCache('<%=obj %>');">
			</td>
		</tr>
	<%}%>
	</table>
	<%}else{ %>
		<table width="100%" align="center" height="50px">
			<tr><td align="center"><font size="5px">当前无缓存页面.....</font></td></tr>
		</table>
	<%}%>
</body>
<script type="text/javascript">
	
	function clearCache(obj){
		if(window.confirm("你确认清楚该页面缓存吗?")){
			$.ajax({
				dataType : 'json',
				url : "auser2!remouveCahce.action",
				cache : false,
				type : 'POST',
				data:{
					"userName":obj
				},
				success : function(data) {
					if(data == "1"){
						alert("清出成功!");
						window.location.reload();
					}
				},
				error : function(XMLHttpRequest, textStatus, errorThrown) {
					alert(textStatus);
				}
			});
		}
	}
</script>
</html>


action

//清出
	public void remouveCahce() throws IOException{
		response.setContentType("application/json");
		response.setCharacterEncoding("utf-8");
		String urls = this.getUserName().toString();
		CacheManager manager = CacheManager.create();
		BlockingCache cache = new BlockingCache(manager.getEhcache("SimplePageCachingFilter"));
		
		for(Object obj:cache.getKeys()){
			if(obj.toString().matches(urls)){
				cache.remove(obj);
			}
		}
		response.getWriter().write(new Gson().toJson("1"));
	}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值