注:1、放入cache中,采用@Cacheable;使緩存失效@CacheEvict
2、自定義CacheManager只需要繼承org.springframework.cache.support.AbstractCacheManager(該類中的map采用了ConcurrentHashMap,解決了並發等問題,可以自己去看原代碼),
然后需要自己實現loadCaches方法,同時也可以實現getCaches方法(如下面代碼)
3、@Cacheable和@CacheEvict中對應的value為為spring配置文件中配置對應,key為放入緩存中的key
key的常用寫法:一、直接寫死,這種方法比較適合固定唯一的key
如:@Cacheable(value="indexCache", key="'web_index_adv_top'")
二、動態,帶參數(注意不支持Constants),下面列子中的#這些都是傳入的參數,condition是條件(例子中是加入緩存的條件)
如:@Cacheable(value="indexCache", key="'web_index_goods_'+#columnId+'_' + #param.page +'_' + #param.size", condition="#param.page <=2")
public SearchResult<IndexGoodsBean> queryByParam(long columnId, PageParam param) {
4、注意@Cacheable是把方法的結果放入了緩存;@CacheEvict是將key從緩存中移除(注意這里移除的理解)
實現步驟:
一、自定義CacheManager
二、spring配置文件(CacheManager和caches,集成redis,cache可以多個;注意這里的caches對應於@Cacheable和@CacheEvict中對應的value)
三、CacheService(也可以采用service,我這里分成了好幾個項目,有parent、support、core、web、admin,core中寫的是共用dao和共用的service,所以我的結構是web中的service調用web中的cacheService,然后web中的cacheService調用core的service,緩存是在web中的cacheService中實現)
四、@Cacheable和@CacheEvict注解寫完整
下面來看完整實現
一、自定義CacheManager(我這里提供緩存的是redis)
import java.util.Collection;
import org.springframework.cache.Cache;
import org.springframework.cache.support.AbstractCacheManager;
public class RedisCacheManager extends AbstractCacheManager {
private Collection<Cache> caches;
@Override
protected Collection<? extends Cache> loadCaches() {
return this.caches;
}
public Collection<Cache> getCaches() {
return caches;
}
public void setCaches(Collection<Cache> caches) {
this.caches = caches;
}
}
二、spring配置文件(配置cacheManager,caches,集成redis)
<cache:annotation-driven />
<!--這里的class就是上面定義的cacheManager-->
<bean id="cacheManager" class="com.xxx.core.aop.RedisCacheManager">
<property name="caches">
<set>
<ref bean="indexCache"/>
</set>
</property>
</bean>
<bean id="indexCache" class="com.xxx.core.aop.RedisCache">
<property name="name" value="indexCache" />
<!--注入org.springframework.data.redis.core.StringRedisTemplate,這種寫法很奇怪吧,你可以手動把這個類配置進也可以-->
<property name="stringRedisTemplate" ref="stringRedisTemplate" />
<property name="expireTime" value="300" />
</bean>
三、
import org.springframework.cache.annotation.Cacheable;
@Service
public class IndexAdvWebCacheServiceImpl implements IndexAdvWebCacheService{
@Autowired
private AdvColumnService advColumnService;
@Autowired
private AdvService advService;
/**頂部廣告位*/
public AdvColumnBean getAdvColumnTop() {
return advColumnService.getByPosition(AdvColumnBean.POSTION_TOP_VALUE);
}
/**
* 頭部廣告位
* 廣告位中的廣告
*/
public List<AdvBean> advInpire(long columnId) {
List<AdvBean> list = CopyUtil.copyList(advService.getByColumnIdInpire(columnId), AdvBean.class);
Collections.sort(list, new AdvComparator());
return list;
}
private static class AdvComparator implements Comparator<AdvBean> {
@Override
public int compare(AdvBean arg0, AdvBean arg1) {
if(null == arg0 || null == arg1){
return 0;
}
if(arg0.getSortIndex() > arg1.getSortIndex()){
return 1;
}
if(arg0.getSortIndex() < arg1.getSortIndex()){
return -1;
}
return 0;
}
}
//我這里的key是可以固定的,如果不是固定的可以使用@Cacheable的語法來使用
@Override
@Cacheable(value="indexCache", key="'web_index_adv_top'")
public List<AdvBean> advTop() {
if(getAdvColumnTop() != null) {
return advInpire(getAdvColumnTop().getId());
}
return new ArrayList<AdvBean>();
}
}
//使緩存失效@CacheEvict
import org.springframework.cache.annotation.CacheEvict;
@Service
public class AdvAdminCacheServiceImpl implements AdvAdminCacheService{
@Autowired
private AdvService advService;
@Override
@CacheEvict(value="indexCache", key="'web_index_adv_top'")
public boolean updateOne(AdvBean bean) {
return advService.updateOne(bean);
}
@Override
@CacheEvict(value="indexCache", key="'web_index_adv_top'")
public long save(AdvBean bean) {
return advService.save(bean);
}
@Override
@CacheEvict(value="indexCache", key="'web_index_adv_top'")
public boolean deleteByIds(long[] ids) {
return advService.deleteByIds(ids);
}
}