最近遇到一个新需求:用户多次点击提交订单发生多次扣款,一开始准备配置数据库事务,但后来发现这种方法白白浪费很多资源,就改为利用接口上的切面对请求做拦截,并将当前登陆的用户存进Redis缓存,废话不说了直接上代码;

AOP的应用(模拟请求拦截器):

/**
* @author YHW
* @ClassName: ApiMemberAspect
* @Description:
* @date 2019/3/21 8:54
*/
@Aspect
@Configuration
public aspect ApiMemberAspect { private Logger logger = LoggerFactory.getLogger(getClass()); private static Gson gson = new Gson(); //切点绑在注解上方便重用!
@Pointcut("@annotation(io.renren.common.annotation.RepetitionCheck)")
public void ApiLogPointCut() { } @Before("ApiLogPointCut()")
public void beforeCheck(JoinPoint joinPoint) throws Throwable {
Object[] paramValues = joinPoint.getArgs();
String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
for(int i = 0; i < paramNames.length; i++){
if("payType".equals(paramNames[i]) && paramValues[i] != null){
if(!"membercard".equals(paramValues[i])){
return;
}
}
}
for(int i = 0; i < paramNames.length; i++){
if ("mobile".equals(paramNames[i]) && paramValues[i] != null) {
String phone = (String)paramValues[i];
logger.info(phone);
RedisUtils redisUtils = new RedisUtils();
if(redisUtils.get(phone) != null){
throw new RRException("操作超时,请等待一会后重试");
}else{
redisUtils.set(phone,phone);
}
}
}
} @After("ApiLogPointCut()")
public void afterCheck(JoinPoint joinPoint) throws Throwable{
Object[] paramValues = joinPoint.getArgs();
String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
for(int i = 0; i < paramNames.length; i++){
if ("mobile".equals(paramNames[i]) && paramValues[i] != null) {
String phone = (String)paramValues[i];
logger.info(phone);
RedisUtils redisUtils = new RedisUtils();
if(redisUtils.get(phone) != null){
redisUtils.delete(phone);
}
}
} } @AfterThrowing("ApiLogPointCut()")
public void afterException(JoinPoint joinPoint) throws Throwable{ Object[] paramValues = joinPoint.getArgs();
String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
for(int i = 0; i < paramNames.length; i++) {
if ("mobile".equals(paramNames[i]) && paramValues[i] != null) {
String phone = (String)paramValues[i];
logger.info(phone);
RedisUtils redisUtils = new RedisUtils();
if(redisUtils.get(phone) != null){
redisUtils.delete(phone);
}
}
} } }

下面是注解类:

/**
* @author YHW
* @ClassName: RepetitionCheck
* @Description:
* @date 2019/3/21 8:58
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RepetitionCheck {
String value() default "";
}

关于Redis就不多提了,自己也是处于只会用用的阶段,以后学习完会单独开一篇Redis专题;

Spring AOP初步总结(三)的更多相关文章

  1. spring AOP详解三

    CGLib采用非常底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截的结束拦截所有父类方法的调用,并顺势织入横切逻辑.我们采用CGLib技术可以编写一个可以为任何类创建织入横切逻辑代理对象 ...

  2. 深入源码解析spring aop实现的三个过程

    Spring AOP的面向切面编程,是面向对象编程的一种补充,用于处理系统中分布的各个模块的横切关注点,比如说事务管理.日志.缓存等.它是使用动态代理实现的,在内存中临时为方法生成一个AOP对象,这个 ...

  3. Spring AOP实现方式三之自动扫描注入【附源码】

    注解AOP实现  这里唯一不同的就是application 里面 不需要配置每个bean都需要配置了,直接自动扫描 注册,主要知识点是怎么通过配置文件得到bean, 注意类前面的@注解. 源码结构: ...

  4. Spring AOP实现方式三【附源码】

    注解AOP实现 源码结构: 1.首先我们新建一个接口,love 谈恋爱接口. package com.spring.aop; /** * 谈恋爱接口 * * @author Administrator ...

  5. Spring AOP初步总结(二)

    该篇为Spring AOP的一个应用案例:系统日志 需求:将任何删除,更改或新增数据库的操作汇总到数据库中 步骤1:编写切面 @Aspect @Component public class SysLo ...

  6. Spring AOP初步总结(一)

    学习AOP有段时间了,一直没空总结一下,导致有些知识点都遗忘了,之后会把以前学过的Spring核心相关的知识点总结一轮... 先大体介绍下Spring AOP的特点(均摘自"Spring i ...

  7. Spring源码窥探之:Spring AOP初步

    AOP(Aspect Oriented Programming):即我们常说的面向切面编程. 什么是AOP?AOP是在我们原来写的代码的基础上,进行一定的包装,比如在方法执行前.方法返回后.方法抛出异 ...

  8. Spring AOP 简介(三)

    Spring AOP 简介 如果说 IoC 是 Spring 的核心,那么面向切面编程就是 Spring 最为重要的功能之一了,在数据库事务中切面编程被广泛使用. AOP 即 Aspect Orien ...

  9. Spring源码窥探之:Spring AOP初步使用

    AOP即面向切面编程.它的底层实际是用了spring的动态代理,具体是JDK的代理还是CGLIB的代理,就视情况而定了.本博客园仅仅作为平时记录,显得有些杂乱无章,如果想了解动态代理,设计模式,请访问 ...

随机推荐

  1. Java探索之旅(15)——包装类和字符类

    1.包装类 ❶出于对性能的考虑,并不把基本数据类型作为对象使用,因为适用对象需要额外的系统花销.但是某些Java方法,需要对象作为参数,例如数组线性表ArrayList.add(Object).Jav ...

  2. Unity添加自定义快捷键——UGUI快捷键

    在Editor下监听按键有以下几种方式: 自定义菜单栏功能: using UnityEngine; using UnityEditor; public static class MyMenuComma ...

  3. 利用包管理器安装Node.JS

    步骤1:用curl获取源代码在我们用卷曲获取源代码之前,我们必须先升级操作系统,然后用卷发命令获取NodeSource添加到本地仓库. root@ubuntu-15:~#apt-get update安 ...

  4. Windows下安装MySQL压缩zip包

    MySQL 是最流行的关系型数据库管理系统,在WEB应用方面 MySQL 是最好的RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之 ...

  5. haml

    创建: 2019/05/23 文档: http://haml.info/docs/yardoc/file.REFERENCE.html 安装  安装 gem "haml"     ...

  6. webpack@3.6.0(1) -- 快速开始

    本篇内容 前言 配置入口和输出 热更新 loader配置 js代码压缩 html的打包与发布 前言 //全局安装 npm install -g webpack(3.6.0) npm init //安装 ...

  7. python的virtualenv环境与使用

    1.安装virtualenv 在安装virtualenv之前,我们需要安装至少有一个版本的Python:因为virtualenv是python的一个第三方模块,必须基于python环境才能安装: 如果 ...

  8. [转] ios打包IPA的各种问题和解决方法

    最近做了一个东西,在打包ipa文件时遇到了各种问题,纠结了我好几天. 由于我一直是做android的,在打包时以为ios打包也和android一样:用IDE(eclipse)生成一个签名证书,然后打包 ...

  9. 5.Python初窥门径(字典)

    Python字典学习 1.字典初识 ​ 1.字典的简单介绍 ​ 字典(dict),是python中唯一的映射类型.他是以{ }括起来的键值对组成.在dict中key是唯一的.在保存的时候,根据key来 ...

  10. > Task :app:transformDexArchiveWithExternalLibsDexMergerForDebug FAILED

    > Task :app:transformDexArchiveWithExternalLibsDexMergerForDebug FAILED D8: Cannot fit requested ...