Atitit SpringCache缓存使用
扫描二维码
随时随地手机看文章
Atitit SpringCache缓存使用 艾提拉 attilax总结
1. Spring的抽象已经做得够好了,适合于大多数场景,非常复杂的就需要自己AOP实现了。 1
1.1. 设置配置文件支持 applicataion.xml 1
1.2. -------------通过注解去使用到Cache--- 3
1.3. @Cacheable-------使用这个注解的方法在执行后会缓存其返回结果。 3
1.4. @CachePut 应用到写数据的方法上,如新增/修改方法,调用方法时会自动把相应的数据放入缓存: 4
1.4.1. @CacheEvict 即应用到移除数据的方法上,如删除方法,调用方法时会从缓存中移除相应的数据: 4
1.4.2. @Caching 组合多个Cache注解使用 4
1.4.3. 自定义缓存注解 4
1.5. 测试 4
2. 总结 5
2.1. key的设置 默认以参数作为key 5
2.2. 定时刷新的问题 5
2.3. 不同的方法使用不同的缓存以及缓存时间 6
3. Spring cache独立使用的模式 6
4. 不足之处 8
5. 参考资料 8
设置配置文件支持 applicataion.xml
1. Spring的抽象已经做得够好了,适合于大多数场景,非常复杂的就需要自己AOP实现了。 1.1. 设置配置文件支持 applicataion.xml
<beans default-lazy-init="true" 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:context="http://www.springframework.org/schema/context"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd" >
<bean id="cacheManager"
class="org.springframework.cache.concurrent.ConcurrentMapCacheManager" />
1.2. -------------通过注解去使用到Cache--- 1.3. @Cacheable-------使用这个注解的方法在执行后会缓存其返回结果。
应用到读取数据的方法上,即可缓存的方法,如查找方法:先从缓存中读取,如果没有再调用方法获取数据,然后把数据添加到缓存中:
package com.cnhis.cloudhealth.clinical.clidoctor.acolsetting.dao;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;
import com.alibaba.fastjson.JSON;
import com.cnhis.cloudhealth.clinical.util.SpringUtilV3_prjcli;
import com.cnhis.cloudhealth.commons.Mappers.ModelVo;
import com.cnhis.cloudhealth.commons.dao.BaseDao;
import com.google.common.collect.Maps;
@SuppressWarnings("rawtypes")
@Repository
public class IcolSettingDao extends BaseDao {
@Cacheable(value = { "Cachename1" })
public Object getSetting(Map map) {
try {
return getSqlSession().selectList("IcolSetting.select_datadic", map);
} catch (Exception e) {
throw new RuntimeException(e);
}
//return new ModelVo();// Maps.newConcurrentMap();
}
1.4. @CachePut 应用到写数据的方法上,如新增/修改方法,调用方法时会自动把相应的数据放入缓存: 1.4.1. @CacheEvict 即应用到移除数据的方法上,如删除方法,调用方法时会从缓存中移除相应的数据:
1.4.2. @Caching 组合多个Cache注解使用
有时候我们可能组合多个Cache注解使用;比如用户新增成功后,我们要添加id-->user;username--->user;email--->user的缓存;此时就需要@Caching组合多个注解标签了。
如用户新增成功后,添加id-->user;username--->user;email--->user到缓存;
Java代码
1. @Caching(
2. put = {
3. @CachePut(value = "user", key = "#user.id"),
4. @CachePut(value = "user", key = "#user.username"),
5. @CachePut(value = "user", key = "#user.email")
6. }
7. )
8. public User save(User user) {
1.4.3. 自定义缓存注解
比如之前的那个@Caching组合,会让方法上的注解显得整个代码比较乱,此时可以使用自定义注解把这些注解组合到一个注解中,如:
1.5. 测试
SpringUtilV3_prjcli.cfgFileDir="C:\0wkspc\clis413\clinical\springtest_cli";
SpringUtilV3_prjcli.setLocations(cfgFileDir,"applicationContext-datasource.xml,onehis-dubbo.xml");
IcolSettingDao d=(IcolSettingDao) SpringUtilV3_prjcli.getBean( IcolSettingDao.class);
//gene_barcode_test();
ConcurrentMap
Object setting = d.getSetting(newConcurrentMap);
System.out.println(setting);
Object setting2 = d.getSetting(newConcurrentMap);
System.out.println(setting2);
2. 总结 2.1. key的设置 默认以参数作为key
@Cacheable(value="缓存空间的名称,xml中配置的" , key = "#spittle.id")--spittle是参数里面的spittle,如果不设置,就以参数作为key
Spittle save(Spittle spittle);
2.2. 定时刷新的问题
· 缓存失效时间支持在方法的注解上指定
Spring Cache默认是不支持在@Cacheable上添加过期时间的,可以在配置缓存容器时统一指定:
@Bean
ConcurrentMapCacheManager可以作为一种缓存方案,但不能设置过期,最大缓存条目等,需进行改造。
class="com.cnhis.cloudhealth.clinical.util.cache.MyConcurrentMapCacheManager">
其实也可以timer to refresh
2.3. 不同的方法使用不同的缓存以及缓存时间
还可以使用不同的多个 CacheManager 每个,cm时间不同即可。。注意cache那么也不要重复了,可以增加个cm前缀命名空间。。
另外还提供了CompositeCacheManager用于组合CacheManager,即可以从多个CacheManager中轮询得到相应的Cache,如
Java代码
1.
2.
3.
4.
5.
6.
7.
8.
9.
当我们调用cacheManager.getCache(cacheName) 时,会先从第一个cacheManager中查找有没有cacheName的cache,如果没有接着查找第二个,如果最后找不到,因为fallbackToNoOpCache=true,那么将返回一个NOP的Cache否则返回null。
Spring Cache抽象详解,一篇很好的spring Cache的解释文章,结合源码更加让人容易懂 - CSDN博客.html
不同的缓存可以指定cachename
不同的时间,则只好使用不同的定时器,清理指定的缓存
CacheManager CacheManager1= (CacheManager) SpringUtilV3_prjcli.getBean( CacheManager.class);
Cache Cache1=CacheManager1.getCache("Cachename1");
Cache1.clear();
3. Spring cache独立使用的模式
package com.cnhis.cloudhealth.clinical.util.cache;
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import com.google.common.cache.CacheBuilder;
/**
* {@link CacheManager} implementation that lazily builds {@link ConcurrentMapCache}
* instances for each {@link #getCache} request. Also supports a ‘static‘ mode where
* the set of cache names is pre-defined through {@link #setCacheNames}, with no
* dynamic creation of further cache regions at runtime.
*
*
Note: This is by no means a sophisticated CacheManager; it comes with no
* cache configuration options. However, it may be useful for testing or simple
* caching scenarios. For advanced local caching needs, consider
* {@link org.springframework.cache.guava.GuavaCacheManager} or
* {@link org.springframework.cache.ehcache.EhCacheCacheManager}.
*
* @author Juergen Hoeller
* @since 3.1
* @see ConcurrentMapCache
*/
public class MyConcurrentMapCacheManager implements CacheManager {
public static void main(String[] args) {
MyConcurrentMapCacheManager CacheManager2=new MyConcurrentMapCacheManager(20, 1000);
CacheManager2.createConcurrentMapCache("cachename1");
Cache Cache1=CacheManager2.getCache("cachename1");
Cache1.put("k", "vv");
System.out.println(Cache1.get("k").get());
System.out.println(Cache1.get("k2").get()); //if no key ret NullPointerException
}
4. 不足之处
当然Spring Cache注解对于大多数场景够用了,如果场景复杂还是考虑使用AOP吧;如果自己实现请考虑使用Spring Cache API进行缓存抽象。
5. 参考资料
SpringCache缓存初探 - 沐魇 - 博客园.html
Spring Cache抽象详解,一篇很好的spring Cache的解释文章,结合源码更加让人容易懂 - CSDN博客.html (注解全局配置)