Spring AOP初步总结(三)

最近遇到一个新需求:用户多次点击提交订单发生多次扣款,一开始准备配置数据库事务,但后来发现这种方法白白浪费很多资源,就改为利用接口上的切面对请求做拦截,并将当前登陆的用户存进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专题,就酱

原文地址:https://www.cnblogs.com/Joey44/p/10614968.html

时间: 2024-10-17 00:08:19

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

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

Spring AOP的面向切面编程,是面向对象编程的一种补充,用于处理系统中分布的各个模块的横切关注点,比如说事务管理.日志.缓存等.它是使用动态代理实现的,在内存中临时为方法生成一个AOP对象,这个对象包含目标对象的所有方法,在特定的切点做了增强处理,并回调原来的方法. Spring AOP的动态代理主要有两种方式实现,JDK动态代理和cglib动态代理.JDK动态代理通过反射来接收被代理的类,但是被代理的类必须实现接口,核心是InvocationHandler和Proxy类.cglib动态代

Spring AOP 实现原理(三) 使用 使用 CGLIB 生成代理类

CGLIB(Code Generation Library),简单来说,就是一个代码生成类库.它可以在运行时候动态是生成某个类的子类. 此处使用前面定义的 Chinese 类,现在改为直接使用 CGLIB 来生成代理,这个代理类同样可以实现 Spring AOP 代理所达到的效果. 下面先为 CGLIB 提供一个拦截器实现类: public class AroundAdvice implements MethodInterceptor { public Object intercept(Obje

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

注解AOP实现  这里唯一不同的就是application 里面 不需要配置每个bean都需要配置了,直接自动扫描 注册,主要知识点是怎么通过配置文件得到bean, 注意类前面的@注解. 源码结构: 1.首先我们新建一个接口,love 谈恋爱接口. package com.spring.aop; /** * 谈恋爱接口 * * @author Administrator * */ public interface Love { /* * 谈恋爱方法 */ void fallInLove(); v

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

注解AOP实现 源码结构: 1.首先我们新建一个接口,love 谈恋爱接口. package com.spring.aop; /** * 谈恋爱接口 * * @author Administrator * */ public interface Love { /* * 谈恋爱方法 */ void fallInLove(); void test() throws Exception; } .csharpcode, .csharpcode pre { font-size: small; color:

Spring AOP初步总结(一)

学习AOP有段时间了,一直没空总结一下,导致有些知识点都遗忘了,之后会把以前学过的Spring核心相关的知识点总结一轮... 先大体介绍下Spring AOP的特点(均摘自"Spring in action第四版"): Spring支持了AOP,另外还有很多实现了AOP的技术,例如AspectJ,它补充了Spring AOP框架的功能,他们之间有着大量的协作,而且Spring AOP中大量借鉴了AspectJ项目,Spring AOP相对粗粒度,而AspectJ提供更强大更细粒度的控制

Spring基础系列12 -- Spring AOP AspectJ

Spring基础系列12 -- Spring AOP AspectJ 转载:http://www.cnblogs.com/leiOOlei/p/3613352.html 本文讲述使用AspectJ框架实现Spring AOP. 再重复一下Spring AOP中的三个概念, Advice:向程序内部注入的代码. Pointcut:注入Advice的位置,切入点,一般为某方法. Advisor:Advice和Pointcut的结合单元,以便将Advice和Pointcut分开实现灵活配置. Aspe

Spring AOP AspectJ

本文讲述使用AspectJ框架实现Spring AOP. 再重复一下Spring AOP中的三个概念, Advice:向程序内部注入的代码. Pointcut:注入Advice的位置,切入点,一般为某方法. Advisor:Advice和Pointcut的结合单元,以便将Advice和Pointcut分开实现灵活配置. AspectJ是基于注释(Annotation)的,所以需要JDK5.0以上的支持. AspectJ支持的注释类型如下: @Before @After @AfterReturni

spring基础知识(三)——aop

spring基础知识(三)--aop面向切面编程 1.概念术语 aop面向切面编程(Aspect ariented Programming) 在开始之前,需要理解Spring aop 的一些基本的概念术语(总结的个人理解,并非Spring官方定义): 切面(aspect):用来切插业务方法的类. 连接点(joinpoint):是切面类和业务类的连接点,其实就是封装了业务方法的一些基本属性,作为通知的参数来解析. 通知(advice):在切面类中,声明对业务方法做额外处理的方法. 切入点(poin

Spring学习总结(三)——Spring实现AOP的多种方式

AOP(Aspect Oriented Programming)面向切面编程,通过预编译方式和运行期动态代理实现程序功能的横向多模块统一控制的一种技术.AOP是OOP的补充,是Spring框架中的一个重要内容.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率.AOP可以分为静态织入与动态织入,静态织入即在编译前将需织入内容写入目标模块中,这样成本非常高.动态织入则不需要改变目标模块.Spring框架实现了AOP,使用注解