使用spring EL表达式+自定义切面封装缓存模块
需求是这样的,业务代码需要使用到缓存功能以减少数据库压力,使用redis来实现,并且需要生成缓存的key由方法的传参拼接而成(貌似也只能这样才能保证同样的select查询可以使用缓存),简单的方式就是在需要缓存的方法内加上大概这样的逻辑:查询缓存--->没有则查询数据库 --->查询结果以key-value形式放入缓存,这样对业务代码造成了侵入,并且产生大量重复的代码,很不优雅,所以决定自己封装一个缓存模块,在需要缓存的地方只需要加入一个注解即可。
首先自定义一个注解
package com.example.test.aspect; import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface MyCache { String value() default "";
}
定义切面
package com.example.test.aspect; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component; import java.lang.reflect.Method; @Component
@Aspect
public class MyAspect { //切入点,带有Myche注解并且是UserService类下的方法
@Pointcut("@annotation(com.example.test.aspect.MyCache)&&execution(* com.example.test.service.UserService.*(..))")
public void pointCut(){}; @Around("pointCut()")
public Object cache(ProceedingJoinPoint joinPoint)throws Throwable{
//获取方法签名
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
//获取目标方法
Method method = methodSignature.getMethod();
// Method method2 = joinPoint.getTarget().getClass().getMethod(methodSignature.getName(),methodSignature.getParameterTypes());
//获取方法上的注解
MyCache myCache = method.getDeclaredAnnotation(MyCache.class);
//得到el表达式
String el = myCache.value();
//解析el表达式,将#id等替换为参数值
ExpressionParser expressionParser = new SpelExpressionParser();
Expression expression = expressionParser.parseExpression(el);
EvaluationContext context = new StandardEvaluationContext();
String[] parameterNames = methodSignature.getParameterNames();
Object[] args = joinPoint.getArgs();
for (int i = 0; i <parameterNames.length ; i++) {
context.setVariable(parameterNames[i],args[i]);
}
String key = expression.getValue(context).toString();
System.out.println(key);
//根据key从缓存中拿数据,这里省略 //如果缓存中没有则执行目标方法
Object o = joinPoint.proceed();
//将结果放入缓存,这里省略 return o; }
}
测试的service
package com.example.test.service; import com.example.test.aspect.MyCache;
import org.springframework.stereotype.Service; @Service
public class UserService implements UserServiceInterface{ @MyCache("'asd_' + #id")
@Override
public void addUser(String id,String name){
System.out.println(id + "----" + name);
}
}
测试类,这里是springboot项目
package com.example.test; import com.example.test.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class)
@SpringBootTest
public class TestApplicationTests { @Autowired
private UserService userService; @Test
public void contextLoads() {
System.out.println(userService.getClass().getName()); userService.addUser("12345" ,"zhagnsan");
} }
执行结果如下:

修改UserService上的注解为:"'asd_' + #id + '_' + #name",结果如下

使用spring EL表达式+自定义切面封装缓存模块的更多相关文章
- Spring EL表达式和资源调用
Spring EL表达式 Spring EL-Spring表达式语言,支持在xml和注解中使用表达式,类似于在jsp的EL表达式语言. Spring 开发中经常涉及调用各种资源的情况, ...
- 把功能强大的Spring EL表达式应用在.net平台
Spring EL 表达式是什么? Spring3中引入了Spring表达式语言—SpringEL,SpEL是一种强大,简洁的装配Bean的方式,他可以通过运行期间执行的表达式将值装配到我们的属性或构 ...
- EL表达式---自定义函数(转)
EL表达式---自定义函数(转) 有看到一个有趣的应用了,转下来,呵呵!! 1.定义类MyFunction(注意:方法必须为 public static) package com.tgb.jstl; ...
- Spring 在 xml配置文件 或 annotation 注解中 运用Spring EL表达式
Spring EL 一:在Spring xml 配置文件中运用 Spring EL Spring EL 采用 #{Sp Expression Language} 即 #{spring表达式} ...
- EL表达式自定义函数
表达式语言除了可以使用基本的运算符外,还可以使用自定义函数.通过使用自定义函数,加强了表达式语言的功能. EL表达式函数,主要功能是完成对数据的修改,统一化格式: 步骤 1.开发函数处理类,处理类就是 ...
- 解决spring el表达式不起作用
el表达式不起作用,如下图所示 现象: 在显示页面中加入: <%@ page isELIgnored="false" %>就OK了 参考:http://bbs.csdn ...
- java MVEL2/Spring EL表达式、直接调用、反射性能实测
import java.io.Serializable; import java.lang.reflect.Field; import java.util.HashMap; import java.u ...
- spring EL表达式,null-safe表达式
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://ww ...
- Spring整合Shiro并扩展使用EL表达式
Shiro是一个轻量级的权限控制框架,应用非常广泛.本文的重点是介绍Spring整合Shiro,并通过扩展使用Spring的EL表达式,使@RequiresRoles等支持动态的参数.对Shiro的介 ...
随机推荐
- SpringMVC零碎笔记
在web.xml里可以配置webapp的默认首页,格式如下: <welcome-file-list> <welcome-file>index.html</welcome- ...
- webuploader 文件上传插件 IE8/9 文件选择不上传
IE8/9下文件上传是采用flash模式,一直发送http://xxx.xxx.xx.xx:8888/crossdomain.xml请求,状态码为404,原因是上传文件的服务器未配置crossdoma ...
- 使用idea,springboot,springsession,redis实现分布式微服务的session 共享
本次开发环境:idea2016.3.4 +jdk1.8+maven3.3.9+redis+springboot+jedis 本文中的项目使用Maven来管理项目依赖,使用Spring Session和 ...
- (网络流) Sabotage -- UVA -- 10480
链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82835#problem/J 代码: #include<cstdio> ...
- (连通图)Network--POJ--3694
链接: http://poj.org/problem?id=3694 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82833#probl ...
- Nonsense Alphabet
Nonsense Alphabet A was an ant Who seldom stood still, And who made a nice house In the side of a hi ...
- PHP环境的搭建及与nginx的集成
1. 去php官网下载最新稳定版(最新其实是7.0,为了兼容性,使用5.6.16) wget http://cn2.php.net/get/php-5.6.16.tar.gz/from/this/m ...
- STS中配置MyBatis代码生成器
1.STS工具菜单项Help > Eclipse Marketplace... 2.输入“mybatis”关键字搜索 3.选择MyBatis Generator 1.3.7进行安装 4.安装成功 ...
- bash基本命令速查表
来源:https://github.com/skywind3000/awesome-cheatsheets/blob/master/languages/bash.sh ################ ...
- jenkins调用本地搭建sendmail邮件服务器发送邮件
应用jenkins发送邮件的邮件服务器 SMTP server 可以是本地的,也可以是远程,远程的就不多说了,在此说一下如何在jenkins本地服务器上搭建邮件服务器,并用jenkins发送邮件,详细 ...