• Redis入门到高可用(十)—— Spring与Redis的整合


    1.pom文件

                <!--redis-->
                 <dependency>
                    <groupId>org.springframework.data</groupId>
                    <artifactId>spring-data-redis</artifactId>
                    <version>1.0.2.RELEASE</version>
                </dependency>
                <dependency>
                    <groupId>redis.clients</groupId>
                    <artifactId>jedis</artifactId>
                    <version>2.1.0</version>
                </dependency>

    2.Redis.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:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
       
       <!--引入Redis配置文件  需要的时候进行配置-->
        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>classpath:config/redis.properties</value>
                </list>
            </property>
        </bean>
        
        <!--引入Redis配置文件 方式二-->
        <!-- <context:property-placeholder location="classpath:properties/redis.properties" ignore-unresolvable="true"/> -->
    
    <!-- jedis 连接池配置 -->
        <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <property name="maxActive" value="10" />
            <property name="maxIdle" value="10"/><!-- "${redis.maxIdle}" -->
            <property name="maxWait" value="1000"/><!--${redis.maxWait}  -->
            <property name="testOnBorrow" value="true"/><!-- ${redis.testOnBorrow} -->
        </bean>
        <!-- redis连接工厂 -->
        <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
            <property name="poolConfig" ref="poolConfig"/>
            <property name="port" value="${redis.port}"/><!--${redis.port}  -->
            <property name="hostName" value="${redis.ip}"/>
            <!-- <property name="password" value="${redis.pass}"/> -->
            <property name="timeout" value="100000"></property><!-- ${redis.timeout} -->
        </bean>
        <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
            <property name="connectionFactory" ref="connectionFactory"/>
            <property name="keySerializer">
                <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
            </property>
            <property name="valueSerializer">
                <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
            </property>
        </bean>
            <!-- cache配置 -->
        <bean id="methodCacheInterceptor" class="cn.com.scooper.interceptor.MethodCacheInterceptor">
            <property name="redisUtil" ref="redisUtil"/>
            <property name="defaultCacheExpireTime" value="${redis.cacheExpireTime}"/><!-- ${redis.cacheExpireTime} -->
            <property name="targetNamesList">
                <list>
                    <value></value>
                </list>
            </property>
            <property name="methodNamesList">
                <list>
                    <value>getAccountStatus</value>
                </list>
            </property>
        </bean>
        <bean id="redisUtil" class="cn.com.scooper.utils.RedisUtil">
            <property name="redisTemplate" ref="redisTemplate"/>
        </bean>
        <!--配置切面拦截方法 -->
        <aop:config >
            <aop:pointcut id="controllerMethodPointcut" expression="execution(* cn.com.scooper.impl..*.*(..))"/>
            <aop:advisor advice-ref="methodCacheInterceptor" pointcut-ref="controllerMethodPointcut"/>
        </aop:config>
    
    </beans> 

    3.Redis配置文件 redis.properties

    redis.host=127.0.0.1
    redis.port=6379
    redis.maxIdle=100
    redis.maxWait=1000
    redis.testOnBorrow=true
    redis.timeout=100000
    defaultCacheExpireTime=3600
    redis.cacheExpireTime=3600

    4.创建拦截器

    package cn.com.scooper.interceptor;
    import org.aopalliance.intercept.MethodInterceptor;
    import org.aopalliance.intercept.MethodInvocation;
    
    import cn.com.scooper.common.annotation.ClearInterceptor;
    import cn.com.scooper.common.annotation.NotToCache;
    import cn.com.scooper.common.constant.CommonConstant;
    import cn.com.scooper.utils.RedisUtil;
    
    import java.util.List;
    
    /**
     * Redis缓存过滤器
     * 主要经过以下步骤:
         1.查看当前方法是否在我们自定义的方法中,如果不是的话就直接返回,不进入拦截器。
         2.之后利用反射获取的类名、方法名、参数生成redis的key。
         3.用key在redis中查询是否已经有缓存。
         4.有缓存就直接返回缓存内容,不再继续查询数据库。
         5.如果没有缓存就查询数据库并将返回信息加入到redis中。
     *
     */
    public class MethodCacheInterceptor implements MethodInterceptor {
        private RedisUtil redisUtil;
        private List<String> targetNamesList; // 禁用缓存的类名列表
        private List<String> methodNamesList; // 禁用缓存的方法列表
        private String defaultCacheExpireTime; // 缓存默认的过期时间
    
        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
            Object value = null;
            String targetName = invocation.getThis().getClass().getName();
            String methodName = invocation.getMethod().getName();
            if (!isAddCache(targetName, methodName)) {
                // 跳过缓存返回结果
                return invocation.proceed();
            }
            Object[] arguments = invocation.getArguments();
            String key = creatCacheKey(targetName, methodName, arguments);
            try {
                // 判断是否有缓存
                if (redisUtil.exists(key)) {
                    return redisUtil.get(key);
                }
                // 写入缓存
                value = invocation.proceed();
                if (invocation.getMethod().getAnnotation(NotToCache.class) == null && value != null ) {
                    final String tkey = key;
                    final Object tvalue = value;
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            if(Long.parseLong(defaultCacheExpireTime) > 0){
                                redisUtil.set(tkey, tvalue, Long.parseLong(defaultCacheExpireTime));
                            }else{
                                redisUtil.set(tkey, tvalue);
                            }
                        }
                    }).start();
                }else if(invocation.getMethod().getAnnotation(NotToCache.class) != null ){
                    redisUtil.removePattern(CommonConstant.KEY_PREFIX+CommonConstant.KEY_SPLIT_CHAR+targetName+"*");
                }
            } catch (Exception e) {
                e.printStackTrace();
                if (value == null) {
                    return invocation.proceed();
                }
            }
            return value;
        }
    
        /**
         * 是否加入缓存
         *
         * @return
         */
        private boolean isAddCache(String targetName, String methodName) {
            boolean flag = true;
            if (targetNamesList.contains(targetName)
                    || methodNamesList.contains(methodName) || targetName.contains("$$EnhancerBySpringCGLIB$$")) {
                flag = false;
            }
            return flag;
        }
    
        /**
         * 创建缓存key
         *
         * @param targetName
         * @param methodName
         * @param arguments
         */
        private String creatCacheKey(String targetName, String methodName,Object[] arguments) {
            
            StringBuffer sbu = new StringBuffer(CommonConstant.KEY_PREFIX);
            sbu.append(CommonConstant.KEY_SPLIT_CHAR).append(targetName).append(CommonConstant.KEY_SPLIT_CHAR).append(methodName);
            if ((arguments != null) && (arguments.length != 0)) {
                for (int i = 0; i < arguments.length; i++) {
                    sbu.append(CommonConstant.KEY_SPLIT_CHAR).append(arguments[i]);
                }
            }
            return sbu.toString();
        }
        
        public void setRedisUtil(RedisUtil redisUtil) {
            this.redisUtil = redisUtil;
        }
    
        public void setTargetNamesList(List<String> targetNamesList) {
            this.targetNamesList = targetNamesList;
        }
    
        public void setMethodNamesList(List<String> methodNamesList) {
            this.methodNamesList = methodNamesList;
        }
    
        public void setDefaultCacheExpireTime(String defaultCacheExpireTime) {
            this.defaultCacheExpireTime = defaultCacheExpireTime;
        }
    }

    5.Redis工具类

    package cn.com.scooper.utils;
    import java.io.Serializable;
    import java.util.Set;
    import java.util.concurrent.TimeUnit;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.ValueOperations;
    /**
     * Redis工具类
     */
    public class RedisUtil {
        private RedisTemplate<Serializable, Object> redisTemplate;
    
        /**
         * 批量删除对应的value
         *
         * @param keys
         */
        public void remove(final String... keys) {
            for (String key : keys) {
                remove(key);
            }
        }
    
        /**
         * 批量删除key
         *
         * @param pattern
         */
        public void removePattern(final String pattern) {
            Set<Serializable> keys = redisTemplate.keys(pattern);
            if (keys.size() > 0){
                for (Serializable key : keys) {
                    redisTemplate.delete(key);
                }
            }
        }
    
        /**
         * 删除对应的value
         *
         * @param key
         */
        public void remove(final String key) {
            if (exists(key)) {
                redisTemplate.delete(key);
            }
        }
    
        /**
         * 判断缓存中是否有对应的value
         *
         * @param key
         * @return
         */
        public boolean exists(final String key) {
            return redisTemplate.hasKey(key);
        }
    
        /**
         * 读取缓存
         *
         * @param key
         * @return
         */
        
        public Object get(final String key) {
            Object result = null;
            ValueOperations<Serializable, Object> operations = redisTemplate
                    .opsForValue();
            result = operations.get(key);
            return result;
        }
    
        /**
         * 写入缓存
         *
         * @param key
         * @param value
         * @return
         */
        public boolean set(final String key, Object value) {
            boolean result = false;
            try {
                ValueOperations<Serializable, Object> operations = redisTemplate
                        .opsForValue();
                operations.set(key, value);
                result = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
    
        /**
         * 写入缓存
         *
         * @param key
         * @param value
         * @return
         */
        public boolean set(final String key, Object value, Long expireTime) {
            boolean result = false;
            try {
                ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
                operations.set(key, value);
                redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
                result = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
    
        public void setRedisTemplate(
                RedisTemplate<Serializable, Object> redisTemplate) {
            this.redisTemplate = redisTemplate;
        }
    }
  • 相关阅读:
    Funny Car Racing
    [LDUoj 倍增] 题解
    [HDU7073] Integers Have Friends 2.0 -随机大法好
    【spring】全局异常 globalexception 处理
    【maven】测试
    【spring】spring aop
    jvm常用排错命令
    idea tools
    idea插件
    【maven】搭建maven私服--基于CentOS7.6+docker
  • 原文地址:https://www.cnblogs.com/thiaoqueen/p/9136699.html
Copyright © 2020-2023  润新知