目录
一、需求说明
为了简化代码,提示可读性需要针对优先读缓存,如果缓存没有则插入数据库然后再将数据写入缓存并返回。
根据这个需求我们可以基于Spring AOP 去实现。但是有一个问题,缓存的key是一个动态值,对于不同入参它的key是不同的。我们可以使用SpringEL 表达式去解决这个问题。
预期的效果是:
@Cache(prefix = "test", value = "#bizId", expire = CacheTime.CACHE_EXP_DAY) public Object queryFromCache(Long bizId)
二、Spring AOP
首先我们先了解一下Spring AOP的基础知识
2.1 AOP切点指示器
| AspectJ 指示器 | 描述 |
| args() | 限制连接点匹配参数为执行类型的执行方法 |
| @args() | 限制连接点匹配参数由执行注解标注的执行方法 |
| execution() | 匹配连接点的执行方法 |
| this() | 限制连接点匹配AOP代理的Bean引用类型为指定类型的Bean |
| target() | 限制连接点匹配目标对象为指定类型的类 |
| @target() | 限制连接点匹配目标对象被指定的注解标注的类 |
| within() | 限制连接点匹配匹配指定的类型 |
| @within() | 限制连接点匹配指定注解标注的类型 |
| @annotation | 限制匹配带有指定注解的连接点 |
Spring AOP 中常用的是:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)
throws-pattern?)
2.2 AOP表达式
| 表达式 | 说明 |
| execution("* *.*(..)") | 匹配所有 |
| execution("* *.set*(..)) | 匹配所有以set开头的方法 |
| execution("* com.david.biz.service.impl.*(..)) | 匹配指定包下所有的方法 |
| execution("* com.david..*(..)") | 匹配指定包以及其子包下的所有方法 |
| execution("* com.david..*(java.lang.String)) | 匹配指定包以及其子包下 参数类型为String 的方法 |
2.3、Spring AOP通知类型
| 通知类型 | 说明 |
| 前置通知(Before) | 在目标方法被调用之前调用通知功能。 |
| 后置通知(After) | 在目标方法完成之后调用通知,此时不会关心方法的输出是什么 |
| 返回通知(After-returning) | 在目标方法成功执行之后调用通知。 |
| 异常通知(After-throwing) | 目标方法抛出异常后调用通知。 |
| 环绕通知(Around) | 通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。 |
2.4、示例代码
/**
* execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)
throws-pattern?)
*arg() 限制连接点匹配参数为指定类型的执行方法
*@args() 限制连接点匹配参数由执行注解标注的执行
*execution() 用于匹配连接点的执行方法
*this() 限制连接点匹配AOP代理的Bean引用为执行类型的类
*target() 限制连接点匹配目标对象为指定类型的类
*@target() 限制连接点匹配特定的执行对象,这些对象应具备指定的注解类型
*@an

本文介绍了一个利用Spring AOP实现动态缓存的需求,通过AOP切点指示器、表达式和通知类型来简化代码。在实现过程中,讨论了如何获取方法参数名称以构建缓存Key,并详细讲解了定义注解、切面以及环绕切面处理的步骤。在遇到无法获取参数名称的问题时,提示检查Maven配置。
最低0.47元/天 解锁文章
301

被折叠的 条评论
为什么被折叠?



