zoukankan      html  css  js  c++  java
  • spring整合redis

    在SSH项目中整合redis

    利用spring中的AOP 对redis进行统一的管理

    1. 相关Jar文件

    下载并导入以下3个Jar文件:

    commons-pool2-2.4.2.jar、jedis-2.3.1.jar、spring-data-redis-1.3.4.RELEASE.jar。

    三个文件分别对应的下载地址:http://www.java2s.com/Code/JarDownload/spring-data/ ,repo1.maven.org/maven2/redis/clients/jedis/,http://commons.apache.org/proper/commons-pool/download_pool.cgi 

    2. Redis配置文件

    在src文件夹下面新建一个redis.properties文件,设置连接Redis的一些属性。

    <?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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    >
    
    <!-- 2.配置通知对象 -->
    <bean name="redisAdvice" class="com.samton.common.redis.RedisAdvice" ></bean>
    <!-- 3.开启使用注解完成织入 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    <property name="maxTotal" value="50" />
    <property name="maxIdle" value="10" />
    <property name="maxWaitMillis" value="1000" />
    <property name="testOnBorrow" value="true" />
    </bean>
    
    <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
    <constructor-arg index="0" ref="jedisPoolConfig" />
    <constructor-arg index="1" value="127.0.0.1" type="java.lang.String"/>
    <constructor-arg index="2" value="6379" type="int" />
    </bean>
    </beans>

    记住一定要在 spring创建jedisPool的时候,指定参数类型。否则会报错 jedis:Cannot open Redis connection due invalid URI

    3. 自定义注解

    在src文件夹下面新建一个注解文件;文件内容如下

    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface InterfaceCacheableDao {
        String key();
        String fieldKey();
        int expireTime() default 3600;
    }

    4. 建立AOP通知类

    在src文件夹下面新建一个通知类,用于解析注解统一管理redis;

    //通知类
    @Aspect
    public class RedisAdvice {
        /**
         * 获取注入对象
         */
        private RedisUtil redisUtil;
        
        public RedisRedisUtil  getRedisUtil () {
            return redisUtil;
        }
        
        public void setRedisUtil (RedisUtil redisUtil) {
            this.redisUtil= redisUtil;
        }
    
        @SuppressWarnings("unchecked")
        @Around("@annotation(com.samton.common.redis.dao.InterfaceCacheableDao)")
        public Object around(ProceedingJoinPoint pjp) throws Throwable {
            Object result =null;
            InterfaceCacheableDao cacheable=null;
            //获取注解上的完整方法
            Method proxyMethod = ((MethodSignature)pjp.getSignature()).getMethod();
            Method soruceMethod = pjp.getTarget().getClass().getMethod(proxyMethod.getName(), proxyMethod.getParameterTypes());
        
            cacheable=soruceMethod.getAnnotation(com.samton.common.redis.dao.InterfaceCacheableDao.class);
            
            if( null == cacheable ){
                cacheable = pjp.getTarget().getClass().getAnnotation(com.samton.common.redis.dao.InterfaceCacheableDao.class);
            }
            //解析注解
            String fieldKey =parseKey(cacheable.fieldKey(),soruceMethod,pjp.getArgs());
            
            //获取方法的返回类型,让缓存可以返回正确的类型
            Class returnType=((MethodSignature)pjp.getSignature()).getReturnType();
            
            //使用redis 的hash进行存取,易于管理
            result= redisUtil.hget(cacheable.key(), fieldKey,returnType);
            
            if( null == result ){
                try {
                    result=pjp.proceed();
                    Assert.notNull(fieldKey);
                    redisUtil.hset(cacheable.key(),fieldKey, result,cacheable.expireTime());
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
            
            return result;
        }
        
        
         /**
         *    获取缓存的key 
         *    key 定义在注解上,支持SPEL表达式
         * @param pjp
         * @return
         */
        private String parseKey(String key,Method method,Object [] args){  
            if(!key.startsWith("#")){
                return key;
            }
            //获取被拦截方法参数名列表和参数 用于匹配spel 表达式的值
            LocalVariableTableParameterNameDiscoverer u =   
                new LocalVariableTableParameterNameDiscoverer();  
            String [] paraNameArr=u.getParameterNames(method);
            
            //使用SPEL进行key的解析
            ExpressionParser parser = new SpelExpressionParser(); 
            //SPEL上下文
            StandardEvaluationContext context = new StandardEvaluationContext();
            //把方法参数放入SPEL上下文中
            for(int i=0;i<paraNameArr.length;i++){
                context.setVariable(paraNameArr[i], args[i]);
            }
            
            return parser.parseExpression(key).getValue(context,String.class);
        }
        
    }

    4. 测试

    在某个方法上面加上注解

    @InterfaceCacheableDao(key="channeDao",fieldKey="#channelId",expireTime=20)
        public List test(int channelId) {
            ......
        }

    大功告成

  • 相关阅读:
    git 的分支体系命令汇总
    git命令行学习思路总结
    angular1.5版本的自我认识
    我最想去的公司啊 -- 幸福面试两小时
    【转】【Asp.Net MVC】asp.net mvc Model验证总结及常用正则表达式
    时间被序列化后的页面显示的问题
    JS组件Bootstrap实现弹出框和提示框效果代码
    Bootstrap组件之导航条
    Bootstrap学习笔记(四)-----Bootstrap每天必学之表单
    Bootstrap学习笔记(三)-----Bootstrap每天必学之表格
  • 原文地址:https://www.cnblogs.com/hhwww/p/10795778.html
Copyright © 2011-2022 走看看