Home  >  Article  >  Java  >  Detailed introduction to the integration of spring cache and redis cache

Detailed introduction to the integration of spring cache and redis cache

零下一度
零下一度Original
2017-06-25 10:42:461288browse

spring cache can basically meet the cache needs of general applications, but the reality is always complicated. When your user volume increases or your performance cannot keep up, you always need to expand. At this time, you may provide memory cache for it. You are not satisfied because it does not support high availability and does not have the ability to persist data. At this time, you need to customize your caching solution. Fortunately, spring has also thought of this.

This article uses spring cache and Redis to integrate to achieve the cache you want.

Let’s configure redis first:

The first step is to install redis. For Baidu, we mainly configure redis.

Add a redis configuration file, which can be placed in the following directory

redis.host=192.168.0.43redis.port=6379redis.pass=2015redis.maxIdle=50redis.maxActive=50redis.maxWait=50redis.testOnBorrow=trueredis.timeout=1000

You also need to configure redis in the spring configuration file

<context:property-placeholder location="classpath:conf/redis.properties" />

    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="${redis.maxIdle}" />
        <property name="maxTotal" value="${redis.maxActive}" />
        <property name="maxWaitMillis" value="${redis.maxWait}" />
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />
    </bean>

    <bean id="connectionFactory"class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="poolConfig" ref="poolConfig" />
        <property name="port" value="${redis.port}" />
        <property name="hostName" value="${redis.host}" />
        <property name="password" value="${redis.pass}" />
        <property name="timeout" value="${redis.timeout}" />
    </bean>

    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="connectionFactory" />
    </bean>

Okay, the configuration of redis is completed.

Now let’s configure spring’s cache:

<?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:cache="http://www.springframework.org/schema/cache"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans.xsd  http://www.springframework.org/schema/cache  http://www.springframework.org/schema/cache/spring-cache.xsd"><cache:annotation-driven />

    <!-- 缓存管理器 -->
    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
        <property name="caches">
            <set>
                <bean class="com.config.SystemRedisCache">
                    <property name="redisTemplate" ref="redisTemplate" />
                    <property name="name" value="default" />
                    <property name="timeout" value="${redis.timeout}" />
                </bean>
                <bean class="com.config.SystemRedisCache">
                    <property name="redisTemplate" ref="redisTemplate" />
                    <property name="name" value="commonService.queryCityListByParentCode" />
                    <property name="timeout" value="${redis.timeout}" />
                </bean>
                <bean class="com.config.SystemRedisCache">
                    <property name="redisTemplate" ref="redisTemplate" />
                    <property name="name"value="commonService.queryIndustryListByParentCode" />
                    <property name="timeout" value="${redis.timeout}" />
                </bean>
                <bean class="com.config.SystemRedisCache">
                    <property name="redisTemplate" ref="redisTemplate" />
                    <property name="name" value="commonService.queryIndustryInfoById" />
                    <property name="timeout" value="${redis.timeout}" />
                </bean>
                <bean class="com.config.SystemRedisCache">
                    <property name="redisTemplate" ref="redisTemplate" />
                    <property name="name" value="commonService.queryIndustryNameByIds" />
                    <property name="timeout" value="${redis.timeout}" />
                </bean>
                <bean class="com.config.SystemRedisCache">
                    <property name="redisTemplate" ref="redisTemplate" />
                    <property name="name" value="commonService.queryCityNameByIds" />
                    <property name="timeout" value="${redis.timeout}" />
                </bean>
                <bean class="com.config.SystemRedisCache">
                    <property name="redisTemplate" ref="redisTemplate" />
                    <property name="name" value="commonService.isSpecialSchool" />
                    <property name="timeout" value="${redis.timeout}" />
                </bean>
                <bean class="com.config.SystemRedisCache">
                    <property name="redisTemplate" ref="redisTemplate" />
                    <property name="name" value="commonService.getProvinceByCity" />
                    <property name="timeout" value="${redis.timeout}" />
                </bean>
                <bean class="com.config.SystemRedisCache">
                    <property name="redisTemplate" ref="redisTemplate" />
                    <property name="name" value="permissionService.queryMenuList" />
                    <property name="timeout" value="${redis.timeout}" />
                </bean>
                <bean class="com.config.SystemRedisCache">
                    <property name="redisTemplate" ref="redisTemplate" />
                    <property name="name" value="permissionService.queryOperationOfMenu" />
                    <property name="timeout" value="${redis.timeout}" />
                </bean>
                <bean class="com.config.SystemRedisCache">
                    <property name="redisTemplate" ref="redisTemplate" />
                    <property name="name" value="roleService.queryAllRole" />
                    <property name="timeout" value="${redis.timeout}" />
                </bean>
                <bean class="com.config.SystemRedisCache">
                    <property name="redisTemplate" ref="redisTemplate" />
                    <property name="name" value="permissionService.queryPermissionTree" />
                    <property name="timeout" value="${redis.timeout}" />
                </bean>
                <bean class="com.config.SystemRedisCache">
                    <property name="redisTemplate" ref="redisTemplate" />
                    <property name="name"value="permissionService.queryPermissaionMenuByRoleCode" />
                    <property name="timeout" value="${redis.timeout}" />
                </bean>
                <bean class="com.config.SystemRedisCache">
                    <property name="redisTemplate" ref="redisTemplate" />
                    <property name="name"value="permissionService.queryAllPermissionByRoleCode" />
                    <property name="timeout" value="${redis.timeout}" />
                </bean>
            </set>
        </property>
        <!-- <property name="fallbackToNoOpCache" value="false"/> -->
    </bean>
</beans>

In fact, the above configuration file has configured the relationship between redis and spring annotation cache into the spring’s xml file. .

The corresponding SystemRedisCache class is a custom cache implementation class that implements the cache interface.

import org.springframework.cache.Cache;import org.springframework.cache.support.SimpleValueWrapper;import org.springframework.dao.DataAccessException;import org.springframework.data.redis.connection.RedisConnection;import org.springframework.data.redis.core.RedisCallback;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.util.StringUtils;/**
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 * 
 * @author Administrator
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选) */public class SystemRedisCache implements Cache {/** * Redis     */private RedisTemplate<String, Object> redisTemplate;/** * 缓存名称     */private String name;/** * 超时时间     */private long timeout;/* * (non-Javadoc)
     * @see org.springframework.cache.Cache#getName()     */@Overridepublic String getName() {return this.name;
    }/* * (non-Javadoc)
     * @see org.springframework.cache.Cache#getNativeCache()     */@Overridepublic Object getNativeCache() {// TODO Auto-generated method stubreturn this.redisTemplate;
    }/* * (non-Javadoc)
     * @see org.springframework.cache.Cache#get(java.lang.Object)     */@Overridepublic ValueWrapper get(Object key) {if (StringUtils.isEmpty(key)) {return null;
        } else {final String finalKey;if (key instanceof String) {
                finalKey = (String) key;
            } else {
                finalKey = key.toString();
            }
            Object object = null;
            object = redisTemplate.execute(new RedisCallback<Object>() {public Object doInRedis(RedisConnection connection) throws DataAccessException {byte[] key = finalKey.getBytes();byte[] value = connection.get(key);if (value == null) {return null;
                    }return SerializableObjectUtil.unserialize(value);
                }
            });return (object != null ? new SimpleValueWrapper(object) : null);
        }
    }/* * (non-Javadoc)
     * @see org.springframework.cache.Cache#get(java.lang.Object, java.lang.Class)     */@SuppressWarnings("unchecked")
    @Overridepublic <T> T get(Object key, Class<T> type) {if (StringUtils.isEmpty(key) || null == type) {return null;
        } else {final String finalKey;final Class<T> finalType = type;if (key instanceof String) {
                finalKey = (String) key;
            } else {
                finalKey = key.toString();
            }final Object object = redisTemplate.execute(new RedisCallback<Object>() {public Object doInRedis(RedisConnection connection) throws DataAccessException {byte[] key = finalKey.getBytes();byte[] value = connection.get(key);if (value == null) {return null;
                    }return SerializableObjectUtil.unserialize(value);
                }
            });if (finalType != null && finalType.isInstance(object) && null != object) {return (T) object;
            } else {return null;
            }
        }
    }/* * (non-Javadoc)
     * @see org.springframework.cache.Cache#put(java.lang.Object, java.lang.Object)     */@Overridepublic void put(final Object key, final Object value) {if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {return;
        } else {final String finalKey;if (key instanceof String) {
                finalKey = (String) key;
            } else {
                finalKey = key.toString();
            }if (!StringUtils.isEmpty(finalKey)) {final Object finalValue = value;
                redisTemplate.execute(new RedisCallback<Boolean>() {
                    @Overridepublic Boolean doInRedis(RedisConnection connection) {
                        connection.set(finalKey.getBytes(), SerializableObjectUtil.serialize(finalValue));// 设置超时间                        connection.expire(finalKey.getBytes(), timeout);return true;
                    }
                });
            }
        }
    }/* * 根据Key 删除缓存     */@Overridepublic void evict(Object key) {if (null != key) {final String finalKey;if (key instanceof String) {
                finalKey = (String) key;
            } else {
                finalKey = key.toString();
            }if (!StringUtils.isEmpty(finalKey)) {
                redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection) throws DataAccessException {return connection.del(finalKey.getBytes());
                    }
                });
            }
        }
    }/* * 清楚系统缓存     */@Overridepublic void clear() {// TODO Auto-generated method stub// redisTemplate.execute(new RedisCallback<String>() {// public String doInRedis(RedisConnection connection) throws DataAccessException {// connection.flushDb();// return "ok";// }// });    }public RedisTemplate<String, Object> getRedisTemplate() {return redisTemplate;
    }public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {this.redisTemplate = redisTemplate;
    }public void setName(String name) {this.name = name;
    }public long getTimeout() {return timeout;
    }public void setTimeout(long timeout) {this.timeout = timeout;
    }
}

The main methods are the get and put methods, and the logic inside is implemented according to our own needs.


Now there is a problem. We found that multiple caches are configured in the configuration file where spring configures its own annotation cache. So how does spring find the corresponding cacheManager? ?

We present it directly to you in code:

/**
 * 
 * 公共接口
 * 
 * @author Administrator
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选) */@Service("commonService")public class CommonServiceImpl implements CommonService {/** * 日志记录器     */private static final Logger LOGGER = LoggerFactory.getLogger(CommonServiceImpl.class);

    @Autowiredprivate DalClient dalClient;/* * @Autowired RedisTemplate<?, ?> redisTemplate;     *//** * 根据名称获取自增序列squence的当前值
     * 
     * @param SequenceName 自增序列名称
     * @return 自增序列当前值
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)     */@Overridepublic String getSequenceByName(String SequenceName) {if (StringUtils.isEmpty(SequenceName)) {
            LOGGER.error("自增序列名称为空,无法返回正常的自增序列值");return null;
        } else {
            Map<String, String> paramMap = new HashMap<String, String>();
            paramMap.put("sequenceName", SequenceName);// 查询sequence当前值Map<String, Object> resultMap = dalClient.queryForMap("common.GET_SEQUENCE_BY_NAME", paramMap);if (null != resultMap && !resultMap.isEmpty()) {return String.valueOf(resultMap.get("sequenceValue"));
            } else {return null;
            }
        }
    }/** * 根据上一级的城市编码 查询 所有下属城市 列表
     * 
     * @param parentCityCode
     * @return * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)     */@Override
    @Cacheable(value = "commonService.queryCityListByParentCode", key = "new String('commonService.queryCityListByParentCode')+#parentCityCode.toString()", condition = "null != #parentCityCode")public List<CityBean> queryCityListByParentCode(final Integer parentCityCode) {
        Map<String, Object> paramMap = new HashMap<String, Object>();if (null != parentCityCode) {// 根据所选省份 \ 城市 查询所属城市列表paramMap.put("parentCityCode", parentCityCode);final List<CityBean> cityListResult = dalClient.queryForList("T_CITY.SELECT_BY_PARENTCODE", paramMap,
                    CityBean.class);return cityListResult;
        } else {final List<CityBean> provinceListResult = dalClient.queryForList("T_CITY.SELECT_ALL_FIRST_STEP_CITY",
                    paramMap, CityBean.class);return provinceListResult;
        }
    }/** * 根据上一级的行业编码 查询 所有下属所有行业
     * 
     * @param parentCityCode
     * @return * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)     */@Override
    @Cacheable(value = "commonService.queryIndustryListByParentCode", key = "new String('commonService.queryIndustryListByParentCode')+#parentIndustryCode.toString", condition = "null != #parentIndustryCode")public List<IndustryBean> queryIndustryListByParentCode(final Integer parentIndustryCode) {
        Map<String, Object> paramMap = new HashMap<String, Object>();if (null != parentIndustryCode) {
            paramMap.put("parentIndustryCode", parentIndustryCode);final List<IndustryBean> industryListResult = dalClient.queryForList("T_INDUSTRY.SELECT_BY_PARENTCODE",
                    paramMap, IndustryBean.class);return industryListResult;
        } else {final List<IndustryBean> industryListResult = dalClient.queryForList("T_INDUSTRY.SELECT_ALL_FIRST_STEP_INDUSTRY", paramMap, IndustryBean.class);return industryListResult;
        }
    }/** * 根据行业编码查询 行业信息
     * 
     * @param industryCode
     * @return * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)     */@Override
    @Cacheable(value = "commonService.queryIndustryInfoById", key = "new String('commonService.queryIndustryInfoById')+#industryCode", condition = "(null != #industryCode) and (#industryCode.length() > 0)")public IndustryBean queryIndustryInfoById(final String industryCode) {if (StringUtils.isEmpty(industryCode)) {return null;
        } else {
            Map<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("industryCode", industryCode);final IndustryBean industryInfoResult = dalClient.queryForObject("T_INDUSTRY.SELECT_BY_ID", paramMap,
                    IndustryBean.class);return industryInfoResult;
        }
    }/** * 递归删除 元素 因为可能存在重复的
     * 
     * @param list 列表
     * @param item 要删除的元素
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)     */private void deleteListElement(ArrayList<String> list, String item) {if (null != list && !list.isEmpty() && StringUtils.isNotBlank(item)) {if (list.contains(item)) {
                list.remove(item);if (list.contains(item)) {
                    deleteListElement(list, item);
                }
            }
        }
    }/** * 根据行业id查询 行业名称
     * 
     * @param industryIds 行业Id可能有多个 以分号分隔
     * @return 行业名称列表
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)     */@Override
    @Cacheable(value = "commonService.queryIndustryNameByIds", key = "new String('commonService.queryIndustryNameByIds')+#industryIds", condition = "null != #industryIds and #industryIds.length() > 0")public List<String> queryIndustryNameByIds(final String industryIds) {if (StringUtils.isBlank(industryIds)) {return null;
        } else {
            String[] industryIdArr = industryIds.split(";");if (null != industryIdArr && industryIdArr.length > 0) {
                ArrayList<String> paramList = new ArrayList<String>();
                paramList.addAll(Arrays.asList(industryIdArr));if (null != paramList && !paramList.isEmpty()) {
                    Map<String, Object> paramMap = new HashMap<String, Object>();
                    paramMap.put("industryIdList", paramList);// 查询行业列表List<IndustryBean> queryResultList = dalClient.queryForList("T_INDUSTRY.SELECT_BY_ID_LIST",
                            paramMap, IndustryBean.class);// 封装查询结果List<String> industryNameList = new ArrayList<String>();if (null != queryResultList && !queryResultList.isEmpty()) {// 遍历查询列表 将已经存在的编码去掉 剩下的 就是 根據编码查询不出行业的 直接将行业的名字返回                        String tempId;for (IndustryBean industryInfo : queryResultList) {if (null != industryInfo) {if (null == industryInfo.getIndustryCode()) {continue;
                                } else {
                                    tempId = industryInfo.getIndustryCode().toString();if (paramList.contains(tempId)) {
                                        deleteListElement(paramList, tempId);
                                    }if (StringUtils.isNotBlank(industryInfo.getIndustryName())) {
                                        industryNameList.add(industryInfo.getIndustryName());
                                    }
                                }
                            }
                        }
                    }// 将根据编码查询不出来 的 行业编码 直接返回                    industryNameList.addAll(paramList);return industryNameList;
                }
            }return null;
        }
    }/** * 根据城市id查询 城市名称
     * 
     * @param industryIds 行业Id可能有多个 以分号分隔
     * @return 行业名称列表
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)     */@Override
    @Cacheable(value = "commonService.queryCityNameByIds", key = "new String('commonService.queryCityNameByIds')+#cityIds", condition = "null != #cityIds and #cityIds.length() > 0")public List<String> queryCityNameByIds(String cityIds) {if (StringUtils.isBlank(cityIds)) {return null;
        } else {
            String replacyedCityIds = cityIds.replace(";", ",");
            String[] industryIdArr = replacyedCityIds.split(",");if (null != industryIdArr && industryIdArr.length > 0) {
                ArrayList<String> paramList = new ArrayList<String>();
                paramList.addAll(Arrays.asList(industryIdArr));if (null != paramList && !paramList.isEmpty()) {
                    Map<String, Object> paramMap = new HashMap<String, Object>();
                    paramMap.put("cityIdList", paramList);// 查询行业列表List<CityBean> queryResultList = dalClient.queryForList("T_CITY.SELECT_BY_ID_LIST", paramMap,
                            CityBean.class);
                    List<String> industryNameList = new ArrayList<String>();if (null != queryResultList && !queryResultList.isEmpty()) {// 遍历查询列表 将已经存在的编码去掉 剩下的 就是 根據编码查询不出行业的 直接将行业的名字返回// 封装查询结果                        String tempId;for (CityBean industryInfo : queryResultList) {if (null != industryInfo) {if (null == industryInfo.getCityCode()) {continue;
                                } else {
                                    tempId = industryInfo.getCityCode().toString();if (paramList.contains(tempId)) {
                                        deleteListElement(paramList, tempId);
                                    }if (StringUtils.isNotBlank(industryInfo.getCityName())) {
                                        industryNameList.add(industryInfo.getCityName());
                                    }
                                }
                            }
                        }
                    }// 将根据编码查询不出来 的 行业编码 直接返回                    industryNameList.addAll(paramList);return industryNameList;
                }
            }return null;
        }
    }/** * 查询第一级所有职位
     * 
     * @return */@Overridepublic List<JobTypeVo> queryFirstJobList() {/* * List<JobTypeVo> redisIndustryListResult = redisTemplate.execute(new RedisCallback<List<JobTypeVo>>() {
         * @Override public List<JobTypeVo> doInRedis(RedisConnection connection) { byte[] industryListList =
         * connection.get((RedisConstants.JOB_FIRST_LIST).getBytes()); if (null != industryListList &&
         * industryListList.length > 0) { return (List<JobTypeVo>) SerializableObjectUtil.unserialize(industryListList);
         * } else { return null; } } }); if (null != redisIndustryListResult && !redisIndustryListResult.isEmpty()) {
         * return redisIndustryListResult; } else {         */final List<JobTypeVo> queryIndustryListResult = dalClient.queryForList("T_JOB_TYPE.SELECT_FIRST_JOB_CODE",null, JobTypeVo.class);/* * if (null != queryIndustryListResult && !queryIndustryListResult.isEmpty()) { redisTemplate.execute(new
         * RedisCallback<Boolean>() {
         * @Override public Boolean doInRedis(RedisConnection connection) {
         * connection.set((RedisConstants.JOB_FIRST_LIST).getBytes(),
         * SerializableObjectUtil.serialize(queryIndustryListResult)); return true; } }); }         */return queryIndustryListResult;/* } */}/** * 查询 对应级别的职位信息
     * 
     * @param typeValue
     * @param jobCode
     * @return */@Overridepublic List<JobTypeBean> queryJobTypeList(final int typeValue, final int jobCode) {/* * List<JobTypeBean> redisIndustryListResult = redisTemplate.execute(new RedisCallback<List<JobTypeBean>>() {
         * @Override public List<JobTypeBean> doInRedis(RedisConnection connection) { byte[] industryListList =
         * connection.get((RedisConstants.JOB_FIRST_LIST + typeValue + jobCode) .getBytes()); if (null !=
         * industryListList && industryListList.length > 0) { return (List<JobTypeBean>)
         * SerializableObjectUtil.unserialize(industryListList); } else { return null; } } }); if (null !=
         * redisIndustryListResult && !redisIndustryListResult.isEmpty()) { return redisIndustryListResult; } else {         */Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("typeValue", typeValue);
        paramMap.put("jobFirstCode", jobCode);final List<JobTypeBean> queryResult = dalClient.queryForList("T_JOB_TYPE.SELECT_BY_JOB_CODE", paramMap,
                JobTypeBean.class);/* * if (null != queryResult && !queryResult.isEmpty()) { redisTemplate.execute(new RedisCallback<Boolean>() {
         * @Override public Boolean doInRedis(RedisConnection connection) {
         * connection.set((RedisConstants.JOB_FIRST_LIST + typeValue + jobCode).getBytes(),
         * SerializableObjectUtil.serialize(queryResult)); return true; } }); }         */return queryResult;/* } */}/** * 判断学校是否 特殊学校
     * 
     * @param schoolName 学校名称
     * @param schoolType 学校分类(1:211 暂无其他)
     * @return true:是, false:否
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)     */@Override
    @Cacheable(value = "commonService.isSpecialSchool", key = "new String('commonService.isSpecialSchool')+#schoolName + #schoolType", condition = "null != #schoolName and null !=#schoolType and #schoolName.length() > 0")public boolean isSpecialSchool(String schoolName, int schoolType) {if (StringUtils.isEmpty(schoolName)) {return false;
        } else {
            Map<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("schoolName", schoolName);
            paramMap.put("schoolType", schoolType);
            Map<String, Object> resultMap = dalClient.queryForMap("T_MY_SPECIAL_SCHOOL.SELECT_BY_NAME_TYPE", paramMap);if (null != resultMap && !resultMap.isEmpty() && resultMap.containsKey("NUM")) {return (long) resultMap.get("NUM") > 0;
            } else {return false;
            }
        }
    }/** * 根据城市名称获取 城市所在 省份名称
     * 
     * @param cityNames
     * @return * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)     */@Override
    @Cacheable(value = "commonService.getProvinceByCity", key = "new String('commonService.getProvinceByCity')+#cityNames", condition = "null != #cityNames and #cityNames.length() > 0")public String getProvinceByCity(final String cityNames) {if (StringUtils.isBlank(cityNames)) {return null;
        } else {
            String[] cityArr = cityNames.split("、");
            Map<String, Object> paramMap = new HashMap<String, Object>();
            Map<String, Object> resultMap;
            String provinceName;
            List<String> provinceLait = new ArrayList<String>();for (String cityName : cityArr) {if (StringUtils.isNotBlank(cityName)) {
                    paramMap.put("cityName", cityName);
                    resultMap = dalClient.queryForMap("T_CITY.SELECT_PROVINCE_NAMEBY_CITY_NAME", paramMap);if (null != resultMap && !resultMap.isEmpty() && resultMap.containsKey("provinceName")) {
                        provinceName = String.valueOf(resultMap.get("provinceName"));if (!provinceLait.contains(provinceName)) {
                            provinceLait.add(provinceName);
                        }
                    }
                }
            }
            StringBuffer sb = new StringBuffer(100);if (!provinceLait.isEmpty()) {for (int i = 0; i < provinceLait.size(); i++) {if (i < provinceLait.size() - 1) {
                        sb.append(provinceLait.get(i)).append(",");
                    } else {
                        sb.append(provinceLait.get(i));
                    }
                }
            }return sb.toString();
        }
    }

The queryCityListByParentCode method is taken as an example:

There is the @Cacheable annotation on this method. This is the annotation cache tag added after spring 3.1. It will find the attribute value of value in the value = "commonService.queryCityListByParentCode" that we configured in the spring xml file. Search for the name attribute. After finding the corresponding configuration file, this method will implement the corresponding logic through our custom cache implementation class. If you are not clear about the meaning of spring annotations, you can first understand the meaning of spring cache annotations.

The above is the detailed content of Detailed introduction to the integration of spring cache and redis cache. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn