`
y806839048
  • 浏览: 1120930 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

cache缓存集成---redis为例

 
阅读更多

分布式缓存;

用redis(ecache,memacahe)

 

用任何一种缓存只有结合多种缓存操作才能实现利用缓存,更新缓存(由于没有想gzip那样有e304标签的对比,共享缓存需要在更新的方法更新,查询的方法查询)

 

(1)用标签的话,清空和缓存的标签同时使用,即可控制刷新缓存的时机

http://tom-seed.iteye.com/blog/2104430

 

 

http://www.cnblogs.com/jianjianyang/p/4933016.html//////////////////////////(好)

 Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值对存放在缓存中,(可以设置key的组合)

 等到下次利用同样的参数来调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回。所以在使用Spring   Cache的时候我们要保证我们缓存的方法对于相同的方法参数要有相同的返回结果。

 使用Spring Cache需要我们做两方面的事:1.声明某些方法使用缓存 2.配置Spring对Cache的支持(参数值最为key)

 值对比参数相同不相同,参数值相同就直接从缓存中拿,参数不同就再查,不断的存不同的参数

 

 

需要注意的是当一个支持缓存的方法在对象内部被调用时是不会触发缓存功能的。@Cacheable可以指定三个属性,value、key和condition。

 

属性一 :value(相当于key的命名空间,不同的命名空间可以有同样的key不会混乱

 

    必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称,为ehcache.xml中的<cache name="myCache"/> 。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组。

 

属性二 :key

 

    缓存的Key,当我们没有指定该属性时,Spring将使用默认策略生成key(表示使用方法的参数类型及参数值作为key),key属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。我们还可以自定义策略:自定义策略是指我们可以通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”

    key的生成策略有两种:一种是默认策略,一种是自定义策略

       ¹默认的key生成策略是通过KeyGenerator生成的,其默认策略如下:

            1.如果方法没有参数,则使用0作为key。

            2.如果只有一个参数的话则使用该参数作为key。

            3.如果参数多余一个的话则使用所有参数的hashCode作为key(这就是key值是一串hashzCode的原因)

        ²自定义策略是指我们可以通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index

 

 

 

属性四 :allEntries(一个缓存(value)中可以缓存很多key对应的值)

 

    是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素,这比一个一个清除元素更有效率。

              @CacheEvict(value="users", allEntries=true)

              public void delete(Integer id) {

                 System.out.println("delete user by id: " + id);

              }

 

属性五 :beforeInvocation

 

    清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。(不管方法是否成功执行,都在方法执行之前就清楚缓存)

             @CacheEvict(value="users", beforeInvocation=true)

             public void delete(Integer id) {

               System.out.println("delete user by id: " + id);

             }

 

注意我们也可以使用ehcache的去除策略最近使用(LRU)"策略,其它还有先入先出FIFO,最少使用LFU,较少使用LRU

 

 

 

基于注解配置:(使用不同的代理决定,标签在接口上是否有用,是否只能作用在public方法上,是否类内部调用无效)(aop的代理方式:jdk,cglib(动态))aspectj静态(注解是否在类上还是接口上,公共方法还是内部方法起作用,都可以配置)

       配置Spring对基于注解的Cache的支持,首先我们需要在Spring的配置文件中引入cache命名空间,其次通过<cache:annotation-driven />就可以启用Spring对基于注解的Cache的支持。

<cache:annotation-driven/>(用不用代理---》什么情况起作用(方法是否公有,内部调用是否起作用,是否接口处))

       <cache:annotation-driven/>有一个mode属性,可选值有proxy和aspectj。默认是使用proxy。当mode为proxy时,只有缓存方法在外部被调用的时候Spring Cache才会发生作用,

       这也就意味着如果一个缓存方法在其声明对象内部被调用时Spring Cache是不会发生作用的。而mode为aspectj时就不会有这种问题。

       另外使用proxy时,只有public方法上的@Cacheable等标注才会起作用,如果需要非public方法上的方法也可以使用Spring Cache时把mode设置为aspectj。(注解非公共方法,内部调用是否起作用)

       此外,<cache:annotation-driven/>还可以指定一个proxy-target-class属性,表示是否要代理class,默认为false。(是否接口上起作用)

       我们前面提到的@Cacheable、@cacheEvict等也可以标注在接口上,这对于基于接口的代理来说是没有什么问题的

       ,但是需要注意的是当我们设置proxy-target-class为true或者mode为aspectj时,是直接基于class进行操作的,定义在接口上的@Cacheable等Cache注解不会被识别到,那对应的Spring 

       Cache也不会起作用了。

 <tx:annotation-driven/>(事务注解扫描)和<cache:annotation-driven/>(缓存注解扫面)这个不同(哪种代理---->什么情况(接口处))

 <tx:annotation-driven transaction-manager="transactionManager" 

                                       proxy-target-class="true"/>

  注意:proxy-target-class属性值决定是基于接口的还是基于类的代理被创建。如果proxy-target-class 属性值被设置为true,那么基于类的代理将起作用(这时需要cglib库)。如果proxy-target-class属值被设置为false或者这个属性被省略,那么标准的JDK 基于接口的代理将起作用。

 

 

即使你未声明 proxy-target-class="true" ,但运行类没有继承接口,spring也会自动使用CGLIB代理。

 

高版本spring自动根据运行类选择 JDK 或 CGLIB 代理

http://blog.csdn.net/centre10/article/details/6847828

 

(2)配置文件制定方法缓存:

 

       需要注意的是<cache:annotation-driven/>只会去寻找定义在同一个ApplicationContext下的@Cacheable等缓存注解。

 

 

http://haohaoxuexi.iteye.com/blog/2123030

http://haohaoxuexi.iteye.com/blog/2123030

 

 

缓存和事务的方式,思想类似对比学习

比如都可基于xml,注解,用的代理决定什么情况起作用

 

(3)key设计示例即问题:

 

//用jredis的方法的话,也是要清空和缓存的方法结合使用,保证缓存及时更新

@Cacheable注解也直接有序列化保存实体的功能

 

@Cacheable("BasSpsxValueDaoImpl.getDefaultValue")

 

@Cacheable(value="TbClientLogServiceImpl.getLogList",key="#param.get('pageSize')")//map类型参数

 

@Cacheable(value="ChainDefinitionSectionMetaSource.getSectionService",key="#root.caches[0].name")//无参数就这样处理

public Section getSectionService(String filterChainDefinitions) {

有参数不能用默认的要不然出错

 

问题一:

maybe you are using named params on classes without debug info? --- key的字段为空导致,无参数的用这个#root.caches[0].name,

有参数的一定用参数(不同参数不同结果)

//实体参数

@Cacheable(value="getMenuItems",key="'id='+#item.id")//用这种拼接的方式可以防止空值造成的这种错误,当然也可加个 condition="#articleComment.article != null "

public List<OpmMenuitem> getMenuItems(OpmMenuitem item) {

// TODO Auto-generated method stub

return opmMenuitemMapper.select(item);

}

@Cacheable(value="getMenuItems",key="'menufolderid='+#item.menufolderid")

public List<OpmMenuitem> getMenuItems(OpmMenuitem item) {

// TODO Auto-generated method stub

return opmMenuitemMapper.select(item);

}

 

问题二:

java.util.HashMap cannot be cast to com.esteel.system.bean.OpmUserRole

at com.esteel.system.controller.LoginController.login(LoginController.java:160)

java.util.HashMap cannot be cast to com.esteel.system.bean.OpmRolelimit,缓存之后变成hashmap  //这种问题往往是直接用id等容易和其他key相同的值作为key,(自己的key被覆盖

在取缓存的时候,去了其他类型的值list<bean>取的key对应list<HashMap>

 

 

List<OpmUserRole> ur=opmUserRoleService.getOpmUserRole(u);

 

@Override

@Cacheable(value="getOpmUserRole",key="#u.userid")

public List<OpmUserRole> getOpmUserRole(OpmUserRole u) {

// TODO Auto-generated method stub

return opmUserRoleMapper.select(u);

}

 

用下面的注解例子:(注解在@Server的实现类的公共方法最保险)

@Cacheable(value="TbClientLogServiceImpl.getLogList",key="'getLogList'+#param.get('pageSize')")

public PageInfo<TbClientLogVo> getLogList(Map<String, Object> param) {}//map类型

 

@Cacheable(value="getMenuItems",key="'menufolderid='+#item.menufolderid")

public List<OpmMenuitem> getMenuItems(OpmMenuitem item) {}//实体类型

@Cacheable(value="getRoleLimtContro",key="#root.caches[0].name")//无参数类型

public List<OpmRolelimitVo> getRoleLimtContro() {}

 

 @Cacheable(value="TbClientLogServiceImpl.getLogList",key="'getLogList'+#param.get('pageSize')+#param.get('pageNum')+#param.get('CUS_USER_ID')")

public PageInfo<TbClientLogVo> getLogList(Map<String, Object> param) {

 

 

http://www.iteye.com/problems/94305

    

 

Failed to deserialize payload

 class invalid for deserialization

 

 

(4)应用配置-缓存配置:

<beans xmlns="http://www.springframework.org/schema/beans"

  xmlns:cache="http://www.springframework.org/schema/cache"

  xmlns:c="http://www.springframework.org/schema/c"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  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/>

 

<!-- redis缓存管理器 -->

<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"

c:template-ref="jedisTemplate" /> //使用的缓存类型

 

应用的话类似事务

 

分享到:
评论

相关推荐

    redis-cache-mybatis

    本项目"redis-cache-mybatis"正是为了实现这一目的,提供了一个可以直接使用的Redis缓存解决方案。 在MyBatis中,Redis缓存主要涉及以下几个核心概念: 1. **配置Redis**:首先,我们需要在应用的配置文件中添加...

    redis++使用说明,windows下编译redis-plus-plus

    "Redis++使用说明,windows下编译Redis-Plus-Plus" 在这篇文章中,我们将详细介绍如何在Windows平台下编译Redis++,包括编译hiredis.lib和Win32_Interop.lib静态库文件的过程,然后安装Cmake并编译Redis++,最后...

    SpringBoot项目+MybatisPlus使用+Redis缓存

    1. **MybatisPlus整合Redis**:在需要缓存的查询方法上添加`@Cacheable`注解,通过Spring Cache抽象层,将结果存储到Redis中。下次请求相同数据时,直接从缓存获取,提高响应速度。 2. **RedisTemplate与...

    go-redis-cache:使用Redis缓存进行微服务

    总之,"go-redis-cache"项目提供了一种在Go语言环境中集成Redis缓存的解决方案。通过正确地使用Redis缓存,我们可以提升微服务的性能,减少数据库负载,同时确保数据一致性。在实际开发过程中,根据业务需求选择合适...

    SpringCache与redis集成,优雅的缓存解决方案.docx

    SpringCache与Redis集成,优雅的缓存解决方案 SpringCache是一种基于Java的缓存解决方案,它可以与Redis集成,提供了一种优雅的缓存解决方案。在本文中,我们将对SpringCache与Redis集成的优雅缓存解决方案进行详细...

    gradle-redis-build-cache,使用redis存储构建工件的渐变构建缓存.zip

    总结来说,`gradle-redis-build-cache`插件通过将构建缓存迁移到Redis,为大型项目和持续集成环境提供了高效的构建加速方案。其开源性质使得开发者可以自由地定制和扩展,以满足特定项目的需求。通过合理配置和使用...

    redis2-nginx-module-0.15

    Redis2-NGINX-Module 是一个用于 NGINX Web 服务器的扩展模块,它允许开发者将 NGINX 与 Redis 数据库集成,实现高效的数据缓存和交互。这个版本是 0.15,它提供了一系列功能,帮助提升 Web 应用的性能,减少数据库...

    springboot 使用spring cache缓存 和 缓存数据落地到redis

    Spring Cache抽象了缓存管理,使得开发者能够方便地在应用中集成缓存功能,无需关心底层实现。在本文中,我们将探讨如何使用Spring Cache以及如何将缓存数据落地到Redis存储。\n\n首先,为了使用Spring Cache,我们...

    springboot 使用spring cache缓存 和 使用fastjson配置redis系列化

    Spring Boot的`spring-boot-starter-cache`模块包含了Spring Cache的基本功能,而`spring-boot-starter-data-redis`则提供了与Redis的集成。同时,为了处理JSON序列化,我们引入了Alibaba的Fastjson库。如下所示: ...

    SpringBootWork-ActiveMQ-Ehcache-Mail-Mybatis-Redis-Schedule-Web.zip

    本项目"SpringBootWork-ActiveMQ-Ehcache-Mail-Mybatis-Redis-Schedule-Web.zip"旨在构建一个全能型的Spring Boot应用,集成了一系列常用组件,为开发者提供了一个高效、便捷的开发环境。 1. **Spring Boot核心**:...

    Python库 | redis-simple-cache-3k-0.0.7.tar.gz

    本文将深入探讨Python中的一个库——redis-simple-cache-3k-0.0.7,它是一个基于Redis的简单缓存解决方案,旨在为Python开发者提供快速、可靠的缓存功能。 Redis,全称为REmote Dictionary Server,是一款开源的、...

    SpringMVC-Mybatis-Shiro-redis-master 权限集成缓存中实例

    配置文件(spring-cache.xml )中已经修改为如下配置: &lt;!-- redis 配置,也可以把配置挪到properties配置文件中,再读取 --&gt; &lt;bean id="jedisPool" class="redis.clients.jedis.JedisPool"&gt; &lt;constructor-...

    shiro-redisson基于Redis的ShiroCache和Session实现

    总之,`shiro-redisson` 为 Shiro 带来了分布式环境下的高效缓存和会话管理,通过利用 Redis 的特性,解决了在大型分布式系统中的安全性和性能挑战。对于需要构建可扩展、高可用的 Java 应用来说,这是一个非常有...

    SpringDataRedis的jar包.rar

    综上所述,Spring Data Redis是一个强大且灵活的工具,可以帮助开发者快速地在Spring应用中集成Redis,从而利用其高速缓存、消息传递和持久化存储的能力。通过深入理解和熟练运用这个库,你可以构建出高效、可扩展的...

    tomcat8.5实现redis集成session所需jar包.zip

    本资源“tomcat8.5实现redis集成session所需jar包.zip”正是为了解决这一问题,它提供了在Tomcat 8.5中集成Redis作为session持久化存储所需的jar文件。 Redis是一种高性能的键值数据库,常被用于缓存、消息中间件...

    从0到1项目搭建-集成 Redis 配置MyBatis二级缓存

    基于 SpringBoot 从0搭建一个企业级开发项目,基于SpringBoot 的项目,并集成MyBatis-Plus、Redis、Druid、Logback ,并使用 Redis 配置 MyBatis 二级缓存。

    mybatis+redis缓存配置

    以`RedisCache`为例,该类需要实现`Cache`接口,并提供必要的缓存操作方法: ```java public class RedisCache implements Cache { private Jedis redisClient = createReids(); private String id; private ...

    Memcache-eAccelerator-APC-Xcache-Redis 五种php缓存加速器特点浅析.docx

    本文将对五种常见的PHP缓存加速器进行分析,包括Memcached、eAccelerator、APC(Alternative PHP Cache)、Xcache以及Redis,以帮助理解它们的特点和适用场景。 首先,Memcached是一个分布式内存对象缓存系统,常...

    mybatis二级缓存扩展-与redis集成

    集成Redis作为二级缓存的优势在于,Redis是一款高效的内存数据结构存储系统,支持多种数据结构如字符串、哈希、列表、集合和有序集合,适合用于缓存。此外,Redis支持主从复制和集群部署,能提供高可用性和数据持久...

    redis-cluster和spring集成,基于cache注解

    综上所述,"redis-cluster和spring集成,基于cache注解" 的项目是一个使用 Spring Cache 集成 Redis 集群的实例,旨在通过注解的方式简化缓存管理,提高应用性能。开发者可以通过导入提供的项目,快速了解和实践这一...

Global site tag (gtag.js) - Google Analytics