java使用redis缓存可以使用jedis框架,jedis操作简单,没有什么复杂的东西需要学习,网上资料很多,随便看看就会了.

将spring与redis缓存集成,其实也是使用jedis框架,只不过spring对它进行了一层封装,并将这层封装库命名为spring-data-redis.

下面将要使用spring-data-redis与jedis的jar包,并通过spring的aop功能,将redis缓存无缝无侵入的整合进来.

1.先下载好依赖包

[html] view
plain
 copy

  1. <dependency>
  2. <groupId>org.springframework</groupId>
  3. <artifactId>spring-core</artifactId>
  4. <version>4.1.1.RELEASE</version>
  5. </dependency>
  6. <!-- 还有spring的其它包,这里不一一贴出-->
[html] view
plain
 copy

  1. <dependency>
  2. <groupId>org.springframework.data</groupId>
  3. <artifactId>spring-data-redis</artifactId>
  4. <version>1.4.1.RELEASE</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>redis.clients</groupId>
  8. <artifactId>jedis</artifactId>
  9. <version>2.6.0</version>
  10. </dependency>

2.再配置spring文件

[html] view
plain
 copy

  1. <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
  2. <property name="minIdle" value="${redis.minIdle}" />
  3. <property name="maxIdle" value="${redis.maxIdle}" />
  4. <property name="maxTotal" value="${redis.maxActive}" />
  5. <property name="maxWaitMillis" value="${redis.maxWait}" />
  6. <property name="testOnBorrow" value="${redis.testOnBorrow}" />
  7. </bean>
  8. <bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
  9. <property name="hostName" value="${redis.host}" />
  10. <property name="port" value="${redis.port}" />
  11. <property name="password" value="${redis.password}" />
  12. <property name="usePool" value="true" />
  13. <property name="poolConfig" ref="poolConfig" />
  14. </bean>
  15. <!-- redis template definition -->
  16. <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
  17. <property name="connectionFactory" ref="jedisConnFactory" />
  18. <property name="keySerializer">
  19. <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
  20. </property>
  21. <property name="valueSerializer">
  22. <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
  23. </property>
  24. <property name="hashKeySerializer">
  25. <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
  26. </property>
  27. <property name="hashValueSerializer">
  28. <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
  29. </property>
  30. </bean>

3.开始编写aop代码

3.1 声明两个注解类,用于定义哪些方法将使用缓存

[java] view
plain
 copy

  1. @Retention(RetentionPolicy.RUNTIME)
  2. @Target({ElementType.METHOD})
  3. public @interface Cacheable {
  4. public enum KeyMode{
  5. DEFAULT,    //只有加了@CacheKey的参数,才加入key后缀中
  6. BASIC,      //只有基本类型参数,才加入key后缀中,如:String,Integer,Long,Short,Boolean
  7. ALL;        //所有参数都加入key后缀
  8. }
  9. public String key() default "";     //缓存key
  10. public KeyMode keyMode() default KeyMode.DEFAULT;       //key的后缀模式
  11. public int expire() default 0;      //缓存多少秒,默认无限期
  12. }
[java] view
plain
 copy

  1. @Retention(RetentionPolicy.RUNTIME)
  2. @Target({ElementType.PARAMETER})
  3. public @interface CacheKey {}

3.2 创建一个Aop拦截器的处理类,用于拦截加了@Cacheable的方法

[java] view
plain
 copy

  1. @Aspect
  2. @Component
  3. public class CacheableAop {
  4. @Autowired private RedisTemplate redisTemplate;
  5. @Around("@annotation(cache)")
  6. public Object cached(final ProceedingJoinPoint pjp,Cacheable cache) throws Throwable {
  7. String key=getCacheKey(pjp, cache);
  8. ValueOperations<String, Object> valueOper=redisTemplate.opsForValue();
  9. Object value=valueOper.get(key);    //从缓存获取数据
  10. if(value!=null) return value;       //如果有数据,则直接返回
  11. value = pjp.proceed();      //跳过缓存,到后端查询数据
  12. if(cache.expire()<=0) {      //如果没有设置过期时间,则无限期缓存
  13. valueOper.set(key, value);
  14. } else {                    //否则设置缓存时间
  15. valueOper.set(key, value,cache.expire(),TimeUnit.SECONDS);
  16. }
  17. return value;
  18. }
  19. /**
  20. * 获取缓存的key值
  21. * @param pjp
  22. * @param cache
  23. * @return
  24. */
  25. private String getCacheKey(ProceedingJoinPoint pjp,Cacheable cache) {
  26. StringBuilder buf=new StringBuilder();
  27. buf.append(pjp.getSignature().getDeclaringTypeName()).append(".").append(pjp.getSignature().getName());
  28. if(cache.key().length()>0) {
  29. buf.append(".").append(cache.key());
  30. }
  31. Object[] args=pjp.getArgs();
  32. if(cache.keyMode()==KeyMode.DEFAULT) {
  33. Annotation[][] pas=((MethodSignature)pjp.getSignature()).getMethod().getParameterAnnotations();
  34. for(int i=0;i<pas.length;i++) {
  35. for(Annotation an:pas[i]) {
  36. if(an instanceof CacheKey) {
  37. buf.append(".").append(args[i].toString());
  38. break;
  39. }
  40. }
  41. }
  42. } else if(cache.keyMode()==KeyMode.BASIC) {
  43. for(Object arg:args) {
  44. if(arg instanceof String) {
  45. buf.append(".").append(arg);
  46. } else if(arg instanceof Integer || arg instanceof Long || arg instanceof Short) {
  47. buf.append(".").append(arg.toString());
  48. } else if(arg instanceof Boolean) {
  49. buf.append(".").append(arg.toString());
  50. }
  51. }
  52. } else if(cache.keyMode()==KeyMode.ALL) {
  53. for(Object arg:args) {
  54. buf.append(".").append(arg.toString());
  55. }
  56. }
  57. return buf.toString();
  58. }
  59. }

4.使用缓存示例

[java] view
plain
 copy

  1. @Service
  2. @Transactional
  3. public class DemoServiceImpl implements DemoService {
  4. @Autowired private DemoDao demoDao;
  5. public List<Demo> findAll() {
  6. return demoDao.findAll();
  7. }
  8. /*
  9. 对get()方法配置使用缓存,缓存有效期为3600秒,缓存的key格式为:{package_name}.DemoServiceImpl.get
  10. 同时为参数配置了@CacheKey后,表示此参数的值将做为key的后缀,此例的key,最终是:{package_name}.DemoServiceImpl.get.{id}
  11. 可以为多个参数配置@CacheKey,拦截器会调用参数的toString()做为key的后缀
  12. 若配置多个@CacheKey参数,那么最终的key格式为:{package_name}.{class_name}.{method}.{arg1}.{arg2}.{...}
  13. */
  14. @Cacheable(expire=3600)
  15. public Demo get(@CacheKey String id) {
  16. return demoDao.get(id);
  17. }
  18. public Demo getByName(String name) {
  19. return demoDao.getByName(name);
  20. }
  21. }
  • 若为名称相同的方法配置缓存,可以在@Cacheable中加入key属性,追加额外的key后缀
  • @Cacheable还有一个KeyMode属性,用于配置哪些参数可以追加到key后缀中,

    默认取值 DEFAULT:表示只有加了@CacheKey的参数才能追加到key后缀

    BASIC:自动将基本类型追加到key后缀,而无需再配置@CacheKey

    ALL:自动将所有参数追加到lkey后缀,而无需再配置@CacheKey

这只是一个初步整合方案,测试可行,还未在生产中使用,实际效果待验正.

spring与redis集成之aop整合方案的更多相关文章

  1. Spring Boot Redis 集成配置(转)

    Spring Boot Redis 集成配置 .embody{ padding:10px 10px 10px; margin:0 -20px; border-bottom:solid 1px #ede ...

  2. mybatis与Spring集成(Aop整合PagerAspect插件)

    目的: Mybatis与spring集成 Aop整合pagehelper插件 Mybatis与spring集成 导入pom依赖 <?xml version="1.0" enc ...

  3. spring boot通过Spring Data Redis集成redis

    在spring boot中,默认集成的redis是Spring Data Redis,Spring Data Redis针对redis提供了非常方便的操作模版RedisTemplate idea中新建 ...

  4. Spring Boot Redis 集成 Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer'

    一.原因:redis集群环境没有开启Keyspace notifications 二.解决办法 @Configuration public class HttpSessionConfig { /** ...

  5. Spring+ehcache+redis两级缓存

    问题描述 场景:我们的应用系统是分布式集群的,可横向扩展的.应用中某个接口操作满足以下一个或多个条件: 1. 接口运行复杂代价大, 2. 接口返回数据量大, 3. 接口的数据基本不会更改, 4. 接口 ...

  6. 【转】Spring的中IoC及AOP

    1. Spring介绍 Spring是轻量级的J2EE应用程序框架.Spring的核心是个轻量级容器(container),实现了IoC(Inversion of Control)模式的容器,Spri ...

  7. spring data redis使用1——连接的创建

    spring data redis集成了几个Redis客户端框架,Jedis , JRedis (Deprecated since 1.7), SRP (Deprecated since 1.7) a ...

  8. Spring Data Redis配置项有多少(不列举具体,只提供找的方法)

    首先,要说明Spring Data Redis集成了很多款客户端,比如Jedis这些. 而如果在注入Bean时,我们一般是可以设置一些项的,比如hostName和port等,对于这些项一般的查找方式通 ...

  9. 使用Spring Data Redis操作Redis(单机版)

    说明:请注意Spring Data Redis的版本以及Spring的版本!最新版本的Spring Data Redis已经去除Jedis的依赖包,需要自行引入,这个是个坑点.并且会与一些低版本的Sp ...

随机推荐

  1. SQL Server 使用ROW_NUMBER()进行分页

    代码示例: WITH domain AS(SELECT ROW_NUMBER() OVER(ORDER BY ID DESC) ids,* FROM dbo.DomainInfo) SELECT * ...

  2. CSS3 grayscale滤镜图片变黑白实例页面

    在网站加入友情链接的LOGO时,因为不同logo颜色的问题,和主题色调可能产生冲突, 我选择用CSS3滤镜让logo变黑白,hover时变回原本的彩色 CSS代码: .gray { -webkit-f ...

  3. STL模板_概念

    模板和STL一.模板的背景知识1.针对不同的类型定义不同函数版本.2.借助参数宏摆脱类型的限制,同时也因为失去的类型检查而引 入风险.3.借助于编译预处理器根据函数宏框架,扩展为针对不同类型的 具体函 ...

  4. WP8.1开发系列之隐藏顶部状态栏

    StatusBar statusbar = StatusBar.GetForCurrentView(); await statusbar.HideAsync(); 只能在后台代码中实现,前台xaml不 ...

  5. R与数据分析旧笔记(六)多元线性分析 下

    逐步回归 向前引入法:从一元回归开始,逐步加快变量,使指标值达到最优为止 向后剔除法:从全变量回归方程开始,逐步删去某个变量,使指标值达到最优为止 逐步筛选法:综合上述两种方法 多元线性回归的核心问题 ...

  6. gmpy2安装使用方法

    GMP(GNU Multiple Precision Arithmetic Library,即GNU高精度算术运算库),它是一个开源的高精度运算库,其中不但有普通的整数.实数.浮点数的高精度运算,还有 ...

  7. 转: when.js原理和核心实现

    这篇文章可以看作是屈屈同学关于when.js的文章<异步编程:When.js快速上手>的续篇. 屈屈的文章中详细介绍了when.js,在这里关于when.js的使用我就不多复述了,大家可以 ...

  8. CentOS ips bonding

    centos ip bonding 一个网卡多个ips,多个网口一个ip 1,配置一个网卡多ips的情况cp /etc/sysconfig/network-scripts/ifcfg-eth0 /et ...

  9. 基于视觉的Web页面分页算法VIPS的实现源代码下载

    基于视觉的Web页面分页算法VIPS的实现源代码下载 - tingya的专栏 - 博客频道 - CSDN.NET 基于视觉的Web页面分页算法VIPS的实现源代码下载 分类: 技术杂烩 2006-04 ...

  10. jquery阻止默认滑动

    $(".swiper-slide").click(function(){ var index = imgarr[$(this).index()]; var content = &q ...