使用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的介 ...
随机推荐
- 大文件webuploader的基本使用
webuploader的简单使用 需要的文件 自备 百度很多 webuploader.js uploader.swf jQuery <!DOCTYPE html> <htm ...
- spring p 标签
需要引入命名空间 xmlns:p="http://www.springframework.org/schema/p" p 是什么含义 p 是 property 的缩写,为了简化be ...
- 使用工厂方法配置bean的两种方式
1.使用静态工厂方法: 对应的配置.xml文件: 2.通过实例工厂的方法来配置bean: 对应的xml文件:
- session token防表单重提
1.表单页面初始化前,先在session存入一个token值,随后把token存放在表单页面隐藏表单域内,开始初始化: 在表单页初始化前,调用ajax请求,在后台生成token,并返回至表单页 fun ...
- 11i AP & GL 月末对账时常用系统报表
11i AP & GL 月末对账时常用系统报表 http://www.cnblogs.com/benio/archive/2011/10/14/2212169.html AP: 1.Invo ...
- Spring Boot 应用系列 2 -- Spring Boot 2 整合MyBatis和Druid
本系列将分别演示单数据源和多数据源的配置和应用,本文先演示单数据源(MySQL)的配置. 1. pom.xml文件配置 需要在dependencies节点添加: <!-- MySQL --> ...
- CSharp程序员学Android开发---3.Android内部元素不填充BUG
最近公司组织项目组成员开发一个Android项目的Demo,之前没有人有Andoid方面的开发经验,都是开发C#的. 虽说项目要求并不是很高,但是对于没有这方面经验的人来说,第一步是最困难的. 项目历 ...
- winform之combobox
绑定键值对: ArrayList mylist = new ArrayList(); mylist.Add(new DictionaryEntry("WinFormURL", &q ...
- Angular6 学习笔记——组件详解之组件通讯
angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...
- Cesium简介 [转]
http://www.cnblogs.com/laixiangran/p/4984522.html 一.Cesium介绍 Cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎. ...