zoukankan      html  css  js  c++  java
  • web开发中对缓存的使用

       很久没有发表随笔了,最近工作不是太忙,抽点时间 给大家谈谈缓存吧 ;

           在我从事web开发的几年实践中  接触了缓存技术 也是比较多的,在最初的 项目当中 我们用到 hibernate 的 一二级缓存,在到后期的 nosql产品  redis,memcache,还有互联网中常用的  页面缓存 oscache

               缓存使用场景介绍

                              一级缓存是对方法层面的缓存 只是类级别的 缓存用处不大  只是在配置当中进行开启

                             二级缓存在SqlFactory  层次的缓存   这样的缓存配置 网上还是很多的  http://www.open-open.com/lib/view/open1413527015465.html

                            下面就说说 大家在开发中常用nosql 缓存了    

                          

          memcache   我在项目中的使用   列子如下 maven为列

    <!-- memcached -->
    <dependency>
    <groupId>com.google.code.maven-play-plugin.spy</groupId>
    <artifactId>memcached</artifactId>
    <version>2.4.2</version>
    </dependency>

    <dependency>
    <groupId>com.danga</groupId>
    <artifactId>memcached</artifactId>
    <version>2.0.1</version>
    </dependency>

    spring AOP下的缓存配置

    <!-- Memcached 配置 -->

    <!-- Memcached 配置 -->
    <bean id="memCachedClient" class="com.danga.MemCached.MemCachedClient">
    <constructor-arg>
    <value>sockIOPool</value>
    </constructor-arg>
    </bean>
    <!-- Memcached连接池 -->
    <bean id="sockIOPool" class="com.danga.MemCached.SockIOPool" factory-method="getInstance" init-method="initialize" destroy-method="shutDown">
    <constructor-arg>
    <value>sockIOPool</value>
    </constructor-arg>
    <property name="servers">
    <list>
    <value>192.168.25.129:11211</value>
    </list>
    </property>
    <property name="weights">
    <list>
    <value>1</value>
    </list>
    </property>
    </bean>

    <!-- 切面对象 -->
    <bean id="cacheInterceptor" class="cn.itcast.common.web.aop.CacheInterceptor">
    <property name="expiry" value="4200000"/>
    </bean>

    <!-- Spring Aop 配置 get* 配置环绕 -->
    <aop:config>
    <!-- 面 -->
    <aop:aspect ref="cacheInterceptor">
    <!-- 点 -->
    <aop:around method="doAround" pointcut="execution(* cn.itcast.core.service.*.*.get*(..))"/>
    <!-- 变更 -->
    <aop:after method="doAfter" pointcut="execution(* cn.itcast.core.service.*.*.update*(..))"/>
    <aop:after method="doAfter" pointcut="execution(* cn.itcast.core.service.*.*.add*(..))"/>
    <aop:after method="doAfter" pointcut="execution(* cn.itcast.core.service.*.*.delete*(..))"/>
    </aop:aspect>
    </aop:config>

    拦截器 

    import java.io.IOException;
    import java.io.StringWriter;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;

    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.codehaus.jackson.JsonGenerationException;
    import org.codehaus.jackson.map.JsonMappingException;
    import org.codehaus.jackson.map.ObjectMapper;
    import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
    import org.springframework.beans.factory.annotation.Autowired;

    import cn.itcast.common.encode.MemCachedUtil;

    import com.danga.MemCached.MemCachedClient;

    /**
    * 缓存Memcached中数据的切面对象
    * aroud
    * after
    * @author lx
    *
    */
    public class CacheInterceptor {

    @Autowired
    private MemCachedClient memCachedClient;

    //时间 缓存时间
    public static final int TIMEOUT = 360000;//秒

    private int expiry = TIMEOUT;

    //配置环绕方法
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
    //去Memcached中看看有没有我们的数据 包名+ 类名 + 方法名 + 参数(多个)
    String cacheKey = getCacheKey(pjp);
    System.out.println(cacheKey);
    //如果Memcached 连接不上呢
    if(memCachedClient.stats().isEmpty()){
    System.out.println("Memcached服务器可能不存在或是连接不上");
    return pjp.proceed();
    }

    //返回值
    if(null == memCachedClient.get(cacheKey)){
    //回Service
    Object proceed = pjp.proceed();
    //先放到Memcached中一份
    memCachedClient.set(cacheKey, proceed,expiry);
    }
    return memCachedClient.get(cacheKey);
    }
    //后置由于数据库数据变更 清理get*
    public void doAfter(JoinPoint jp){
    //包名+ 类名 + 方法名 + 参数(多个) 生成Key
    //包名+ 类名
    String packageName = jp.getTarget().getClass().getName();

    //包名+ 类名 开始的 都清理
    List<String> list = MemCachedUtil.getAllKeys(memCachedClient);

    //遍历
    for(String entry : list){
    if(entry.startsWith(packageName)){
    memCachedClient.delete(entry);
    }
    }
    }





    //包名+ 类名 + 方法名 + 参数(多个) 生成Key
    public String getCacheKey(ProceedingJoinPoint pjp){
    //StringBuiter
    StringBuilder key = new StringBuilder();
    //包名+ 类名 cn.itcast.core.serice.product.ProductServiceImpl.productList
    String packageName = pjp.getTarget().getClass().getName();
    key.append(packageName);
    // 方法名
    String methodName = pjp.getSignature().getName();
    key.append(".").append(methodName);

    //参数(多个)
    Object[] args = pjp.getArgs();

    ObjectMapper om = new ObjectMapper();
    om.setSerializationInclusion(Inclusion.NON_NULL);

    for(Object arg : args){

    //流
    StringWriter str = new StringWriter();

    //对象转Json 写的过程 Json是字符串流
    try {
    om.writeValue(str, arg);
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    //参数
    key.append(".").append(str);
    }

    return key.toString();
    }
    public void setExpiry(int expiry) {
    this.expiry = expiry;
    }


    }

    这就是我的 Memcached   缓存使用 这样的话  我们在开发中 只需要 去写我们代码  遵循我们开始的定义规范  不用去管我们缓存了

  • 相关阅读:
    出现 could not open jvm.cfg 的解决办法
    powerdesigner相关概念理解
    UML建模类图
    LAMP环境折腾
    ThinkPHP学习笔记1
    ubuntu14在kDE界面下的关于eclipse提示框黑色背景的修改!
    LAMP环境安装与apache配置
    Unix网络编程---第四次作业
    Unix网络编程---第三次作业
    Unix网络编程---第二次作业
  • 原文地址:https://www.cnblogs.com/AnKangwenqiang/p/7525253.html
Copyright © 2011-2022 走看看