Der Spring-Cache kann grundsätzlich die Caching-Anforderungen allgemeiner Anwendungen erfüllen, aber die Realität ist immer kompliziert. Wenn Ihr Benutzervolumen zunimmt oder Ihre Leistung nicht mithalten kann, müssen Sie möglicherweise immer den Speicher-Cache bereitstellen Damit sind Sie nicht zufrieden, da die Hochverfügbarkeit nicht unterstützt wird und die Daten nicht gespeichert werden können. Zu diesem Zeitpunkt müssen Sie Ihre Caching-Lösung anpassen. Glücklicherweise hat Spring auch daran gedacht.
In diesem Artikel wird der Spring-Cache zur Integration in Redis verwendet, um den gewünschten Cache zu erreichen.
Lassen Sie uns zuerst Redis konfigurieren:
Der erste Schritt besteht darin, Redis zu installieren. Für dieses Baidu konfigurieren wir hauptsächlich Redis.
Fügen Sie eine Redis-Konfigurationsdatei hinzu, die im folgenden Verzeichnis abgelegt werden kann
redis.host=192.168.0.43redis.port=6379redis.pass=2015redis.maxIdle=50redis.maxActive=50redis.maxWait=50redis.testOnBorrow=trueredis.timeout=1000
Sie müssen Redis auch in der Spring-Konfigurationsdatei konfigurieren
<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, die Konfiguration von Redis ist abgeschlossen.
Jetzt konfigurieren wir den Cache von Spring:
<?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>
Tatsächlich hat die obige Konfigurationsdatei die Beziehung zwischen Redis und Spring Annotation Cache zur XML-Datei von Spring konfiguriert.
Die SystemRedisCache-Klasse, die
entspricht, ist eine benutzerdefinierte Cache-Implementierungsklasse, die die Cache-Schnittstelle implementiert.
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; } }
Die Hauptmethoden sind die Get- und Put-Methoden, und die darin enthaltene Logik wird entsprechend unseren eigenen Anforderungen implementiert.
Wir haben festgestellt, dass in der Konfigurationsdatei von Spring mehrere Caches für die Konfiguration des eigenen Annotations-Cache vorhanden sind.
Wir präsentieren es Ihnen direkt im 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(); } }
Nehmen Sie die Methode queryCityListByParentCode als Beispiel:
Für diese Methode gibt es die Annotation @Cacheable. Dies ist das Annotations-Cache-Tag, das nach Spring 3.1 hinzugefügt wurde. Es sucht nach der XML-Datei, die wir im Frühjahr basierend auf dem Attributwert von value = „commonService“ suchen .queryCityListByParentCode". Suchen Sie nach dem Namensattribut in und finden Sie die entsprechende Konfigurationsdatei. Diese Methode implementiert die entsprechende Logik über unsere benutzerdefinierte Cache-Implementierungsklasse. Wenn Sie sich über die Bedeutung von Federanmerkungen nicht im Klaren sind, können Sie zunächst die Bedeutung von verstehen Spring-Cache-Anmerkungen.
Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in die Integration von Spring Cache und Redis Cache. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!