spring与redis集成之aop整合方案

Spring 4 集成 redis 实现缓存 一 背景 随着Web项目的复杂程度逐渐增加,可能会涉及诸如高并发、海量数据查询的的业务场景也逐渐增多;若频繁的操作数据库,会触发数据库的I/O瓶颈,因此需要加入缓存,尽量减少直接操作数据库的频率和次数;同时在分布式系统中,分布式锁等应用场景也需要依赖redis等缓存数据库;redis作为nosql数据库的代表,拥有广泛的应用场景; 这里介绍下Spring集成redis,实现缓存: 准备工作: 1.引入依赖; <!-- jedis 客户端 --> <dependency> < 阅读详情

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

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

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

1.先下载好依赖包

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

  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文件

  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.      
  9.    <bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">  
  10.        <property name="hostName" value="${redis.host}" />  
  11.        <property name="port" value="${redis.port}" />  
  12.        <property name="password" value="${redis.password}" />  
  13.        <property name="usePool" value="true" />  
  14.        <property name="poolConfig" ref="poolConfig" />  
  15.    </bean>   
  16.      
  17. <!-- redis template definition -->  
  18. <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">  
  19.     <property name="connectionFactory" ref="jedisConnFactory" />  
  20.     <property name="keySerializer">  
  21.         <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />  
  22.     </property>     
  23.     <property name="valueSerializer">  
  24.         <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />  
  25.     </property>  
  26.     <property name="hashKeySerializer">    
  27.        <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>    
  28.     </property>  
  29.     <property name="hashValueSerializer">  
  30.        <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>    
  31.     </property>  
  32. </bean>  

3.开始编写aop代码

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

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

  1. @Retention(RetentionPolicy.RUNTIME)  
  2. @Target({ElementType.PARAMETER})  
  3. public @interface CacheKey {}  
3.2 创建一个Aop拦截器的处理类,用于拦截加了@Cacheable的方法

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

4.使用缓存示例

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

  • 若为名称相同的方法配置缓存,可以在@Cacheable中加入key属性,追加额外的key后缀
  • @Cacheable还有一个KeyMode属性,用于配置哪些参数可以追加到key后缀中,
    默认取值 DEFAULT:表示只有加了@CacheKey的参数才能追加到key后缀
    BASIC:自动将基本类型追加到key后缀,而无需再配置@CacheKey
    ALL:自动将所有参数追加到lkey后缀,而无需再配置@CacheKey

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

Spring 5.0.8+MyBatis 3.4.6+Struts 2.5.16+Redis 全栈整合开发资源包 在企业级Java Web开发中,Spring、Struts和MyBatis三大框架的整合已成为构建高内聚、低耦合系统的主流技术方案。本章系统阐述SSM框架整合的核心目标与架构设计理念,深入剖析各组件职责划分与协作机制。Spring 5.0.8作为核心容器,通过IoC实现Bean统一管理,AOP支持横切逻辑解耦,并基于提供声明式事务控制;Struts 2.5.16位于表现层,依托MVC模式完成请求分发与视图渲染,其拦截器栈机制强化了权限、日志等公共行为处理能力; 阅读详情

相关推荐

精通Spring 4.x企业级应用开发实战指南(含PDF与完整源码)

Spring支持使用@AspectJ风格注解来声明切面,极大简化了配置复杂度。要启用该功能,需在配置类上添加表示优先使用CGLIB代理,即使存在接口也强制子类化。定义切面类时需标注@Aspect和@Component@Aspect@Component// 模拟权限检查if (!代码解释:第4行:定义一个命名切点,匹配所有标记@Secured注解的方法;第7行:前置通知,在匹配方法执行前进行权限校验;第10行:通过模拟当前用户角色判断;

weixin_33759613的博客 1004

AOP入门

1 AOP实现Redis缓存

淡水湖的渴望 297

spring-redis-aop:redis客户端集成spring实现aop方式

spring-redis-aop redis客户端集成spring实现aop方式,方便在程序中使用spring的时候更加方便的使用redis内存数据库, 采用aop的方式主要是为了不去污染业务代码,达到业务逻辑更加清晰易于阅读,在使用过程中可以设置 key的有效时间,也可以开启或者关闭某一个方法的缓存使用(有效方便测试)。也可以通过配置来确定 所有注解过的方法是否使用缓存,在选择存储类型的时候,可以选择String或者Map形势(Set和List还没 有实现,可以自行实现)使用还是很方便的哈

Springboot链接Redis实现AOP防止重复提交

spring boot链接AOP实现防止重复提交

L170311的博客 3801

C#与发那科机器人通信实战:从SDK配置到机械臂控制

本文详细介绍了如何使用C#与发那科机器人进行通信,从SDK配置到机械臂控制的完整实战流程。内容包括环境准备、通信连接建立、机械臂运动控制、异常处理与状态监控,以及高级功能实战,帮助开发者快速掌握工业机器人编程技术。

weixin_42524276的博客 459

Jetson Orin NX系统克隆术:如何快速备份与还原你的开发环境(附完整命令行)

本文详细介绍了Jetson Orin NX系统克隆的完整流程,这是一种超越简单备份的完整镜像方案。通过命令行操作,可实现开发环境(包括引导程序、内核、根文件系统及所有配置)的快速备份与还原,确保批量部署时环境的完全一致性与高效性,尤其适合机器人、边缘AI等项目的团队协作。

weixin_29191081的博客 158

spring4.1与redis集成之aop整合方案

java使用redis缓存可以使用jedis框架,jedis操作简单,没有什么复杂的东西需要学习,网上资料很多,随便看看就会了. 将spring与redis缓存集成,其实也是使用jedis框架,只不过spring对它进行了一层封装,并将这层封装库命名为spring-data-redis. 下面将要使用spring-data-redis与jedis的jar包,并通过spring的aop功

skiof007的专栏 2209

手把手教你用键盘在Ubuntu上给Lerobot机械臂采集HIL-SERL训练数据(附完整配置文件)

本文详细介绍了在Ubuntu系统中使用键盘控制Lerobot机械臂进行HIL-SERL训练数据采集的完整流程。从环境准备、机械臂校准到键盘遥操系统配置和数据采集优化,提供了实战指南和常见问题解决方案,帮助读者高效获取高质量训练数据,推动具身智能和强化学习应用的发展。

weixin_30733003的博客 479

JavaWeb16-Java Web缓存:使用Redis与Ehcache

在现代Web应用架构中,缓存是提升系统性能、降低服务器负载的关键技术。根据权威性能测试数据,合理使用缓存可使应用响应时间减少50%以上,数据库压力降低70%。对于Java Web应用而言,Redis和Ehcache是两种广泛使用的缓存方案——Redis以高性能、分布式特性著称,适合跨节点共享缓存;Ehcache作为本地缓存,以低延迟、易用性见长。本文将系统讲解这两种缓存技术的原理、实践与最佳实践,提供40+完整代码示例,帮助开发者构建高效、可靠的Java Web缓存体系。在深入技术细节前,我们需要先理解缓存

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

Debian 11 下用hostapd+dnsmasq搭建WiFi热点:从命令行到实战(避坑指南)

本文详细介绍了在Debian 11系统上,使用hostapd和dnsmasq从命令行搭建稳定WiFi热点的完整实战流程。内容涵盖环境准备、无线网卡AP模式检查、服务深度配置,并重点提供了从服务启动失败到客户端无法上网等常见问题的系统性排错指南,帮助用户避开配置陷阱,成功创建可用的无线接入点。

CAT789的专栏 776

中兴问天 BE7200MAX SFP 光口用华为猫棒替代光猫完整配置教程

PPPoE 账号密码:若原光猫为 Route 模式,在宽带设置页可见用户名,密码需按 F12 打开浏览器开发者模式,点击密码输入框,查看代码中 “value=” 后的内容即为明文密码。若仍失败,核对 PON 类型是否与运营商网络匹配。PON 认证信息:LOID(逻辑 ID,部分地区含密码)、设备 SN 码(标签或设备信息页)、PON 类型(GPON/EPON,运营商网络类型)。电脑保持与路由器连接,访问路由器管理地址(默认通常为 192.168.5.1,可参考路由器说明书),登录后台。

Gulper_Eel的博客 3352

springboot工作笔记

springboot常见问题

weixin_59522197的博客 767

SpringBoot项目启动后ShardingSphere5.0首次SQL查询慢?这个预热技巧帮你搞定

本文针对SpringBoot项目集成ShardingSphere 5.0后首次SQL查询慢的问题,深入剖析了其根源在于SQL解析引擎的懒加载与缓存初始化。文章提供了三种有效的预热技巧,包括精准的SQL解析引擎预热、简单查询触发全链路预热以及可配置的生产级方案,帮助开发者将初始化成本提前至应用启动阶段,从而消除性能毛刺,提升用户体验与系统稳定性。

chair的专栏 1063

Spring、SpringMVC、SpringBoot及其插件学习笔记集合(持续更新中....)

本文摘要了MyBatis、Thymeleaf和Shiro三个Java开发常用框架的核心内容。MyBatis部分包含配置文件和通用mapper模板;Thymeleaf详细介绍了语法使用,包括数据展示、条件判断、循环遍历等模板标签;Shiro作为安全框架,主要功能涵盖认证、授权等模块。文章通过代码示例和配置说明,为开发者提供了快速上手的参考指南。

何同学 3270

C++11、C++14 和 C++17 标准新特性详解

特性C++11C++14C++17auto类型推导✅范围 for 循环✅Lambda 表达式✅✅✅智能指针✅移动语义✅nullptr✅统一初始化{}✅✅constexpr✅✅✅✅数字分隔符✅结构化绑定✅✅✅文件系统库✅。

h a 6 6 6 c k 为 你解决复杂难题! 441

AI Agent在医疗诊断中的智能应用研究

本文探讨了AIAgent在医疗诊断中的智能应用,分析了其技术原理、实际案例及发展挑战。AIAgent通过机器学习算法处理医疗数据,提升诊断准确性和效率,市场规模预计2025年达200亿美元。核心技术包括数据预处理、深度学习模型和隐私保护方法。应用案例涵盖肺癌筛查、阿尔茨海默病预测等,但面临数据偏差、伦理责任等挑战。未来趋势包括多模态学习、个性化医疗和量子计算融合。随着技术优化和伦理完善,AIAgent将成为医疗体系的重要组成部分。

郑伟强dev的专栏 96

本地搭建搜索Agent(SpringAI + RAG + SearXNG + MCP)

课程链接:https://coding.imooc.com/class/948.html其实现在的Agent平台把这个课的东西都实现得很好用,让我自己搭个agent我也大概率不会选择用这份代码从头搭建。就当手动搭建了下,对原理多些了解吧。

美好的事情即将发生 1176

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Java 安全 13:API 接口限流(防止恶意请求)

Java API接口限流技术解析 摘要 本文深入探讨Java API接口限流技术,从安全需求与实现原理出发,系统分析四种主流限流算法: 固定窗口计数器:实现简单但存在边界问题,适用于非核心接口 滑动窗口计数器:通过子窗口划分提高精度,适合核心业务接口 漏桶算法:强制匀速处理请求,适合数据库写入等场景 令牌桶算法:允许合理突发流量,是电商等场景的理想选择 文章详细对比了各算法的复杂度、精度和适用场景,并提供了流程图解和性能指标说明。针对分布式系统环境,还介绍了基于Redis的分布式限流方案。通过合理的限流策略

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

SpringCache整合Redis实现项目缓存解决方案

前言   说实话,在写这一篇文章之前我一直没有搞懂一个问题。明明我们项目中使用最多的缓存技术就是Redis,用Redis就完全就可以搞定缓存的问题了,为什么还有一个SpringCache,以及SpringCache和Redis之间的区别。 一、 为什么要使用缓存 缓存是将数据直接存入内容中,读取效率比数据库的更高 缓存可以有效地降低数据库压力,为数据库减轻负担 二、 常见的缓存中间件 Redis、Memcached、Guava、Caffeine,其中Redis和Memcached使用的较多,各自也有不同

lingerlan510的博客 1万+

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

上一篇: Spring Boot 部署与服务配置
下一篇: HttpClientUtil
杜引强
博客等级 码龄13年 806粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值