Spring-aop /@Around增强/防止表单一分钟内多次提交

原文链接:Spring-aop /@Around增强/防止表单一分钟内多次提交 – 编程屋

1 前言

        平时我们在开发中,可能会对一些功能进行增强处理。比如对于某一类中所有的方法或者某一类中特定的方法进行增强。此时我们就可能会想到用到SpringAop中的@Aroung环绕功能。

在此篇文章中,我们用定义注解+@Around防止接口一分钟内被多次调用来梳理这个功能。

2 @Around

@Around的作用:

1 可以在目标方法之前进行织入操作,也可以在执行目标方法之后织入增强动作

2 可以决定目标方法在什么时候执行,如何执行,甚至可以阻止目标方法的执行

3 可以改变执行目标方法的参数值,也可以改变执行目标方法之后的返回值;当需要改变目标方法时,只能使用around方法

@Around环绕通知,为什么被称为切面中功能最为强大的通知类型呢,因为它既可以实现@Before通知的功能(将增强功能写在proceedingJoinPoint.proceed()方法之前),也可以实现@After通知的功能(将增强功能写在proceedingJoinPoint.proceed()方法之后)。它也可以同时在拦截方法之前和拦截方法之后同时进行增强(增强功能>>>proceedingJoinPoint.proceed()>>>增强功能)

3 代码演示

步骤一:自定义注解

@Target({ElementType.METHOD})   //作用于方法上
@Retention(RetentionPolicy.RUNTIME)  //运行期有效
public @interface RepeatAnnotation {
}

步骤二:自定义切面

@Aspect
@Component
@Slf4j
public class AroundAspect {

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    private static String REPEAT_KEY = "repeatKey";

    /**
     * 注意: ProceedingJoinPoint只能用于环绕通知,因为ProceedingJoinPoint暴露了proceed()方法
     * @param joinPoint
     * @param repeatAnnotation
     * @return
     */
    @Around(value = "@annotation(repeatAnnotation)")
    public Object annotationAround(ProceedingJoinPoint joinPoint, RepeatAnnotation repeatAnnotation) throws JsonProcessingException {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        log.info("打印请求url:{}", String.format("%s:%s%s", request.getRemoteHost(), request.getRemotePort(), request.getRequestURI()));
        //类名称
        String className = joinPoint.getTarget().getClass().toString();
        //方法名称
        String name = joinPoint.getSignature().getName();
        //参数值
        Object[] args = joinPoint.getArgs();
        ObjectMapper objectMapper = new ObjectMapper();
        log.info("调用前:"+name+"方法参数"+objectMapper.writeValueAsString(args));
        //设置一个防重检查key-value{repeatKey:1}
        Boolean result = redisTemplate.opsForValue().setIfAbsent(REPEAT_KEY, "张三");
        if (result == false){
            return "该请求一分钟只能发送一次";
        }
        redisTemplate.expire(REPEAT_KEY,60, TimeUnit.SECONDS);
        Object proceed = null;
        try {
            proceed = joinPoint.proceed();
        } catch (Throwable throwable) {
            log.error("获取目标方法异常",throwable);
        }
        log.info("调用后:"+name+"返回结果"+objectMapper.writeValueAsString(proceed));
        return proceed;

    }
}

步骤三:Redis配置

public class RedisConfig {

    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();

        template.setConnectionFactory(factory);

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

        ObjectMapper om = new ObjectMapper();

        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

        jackson2JsonRedisSerializer.setObjectMapper(om);

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        // key采用String的序列化方式

        template.setKeySerializer(stringRedisSerializer);

        // hash的key也采用String的序列化方式

        template.setHashKeySerializer(stringRedisSerializer);

        // value序列化方式采用jackson

        template.setValueSerializer(jackson2JsonRedisSerializer);

        // hash的value序列化方式采用jackson

        template.setHashValueSerializer(jackson2JsonRedisSerializer);

        template.afterPropertiesSet();

        return template;

    }
}

步骤四:Redis配置文件

spring:
  redis:
    database: 0 #Redis数据库索引 默认是0
    host: 47.118.53.22  #redis服务器地址
    port: 6379 #redis连接端口
    password:       #redis连接密码默认没有
    jedis:
      pool:
        max-wait: -1ms  #连接池最大阻塞时间 使用负值表示没有限制
        max-active: 8   #连接池最大连接数 使用负值表示没有限制
        max-idle: 8     #连接池中的最大空闲连接
        min-idle: 0     #连接池中的最小空闲连接
    connect-timeout: 5000 #连接超时时间

步骤五:访问接口

以上只是部分内容,为了维护方便,本文已迁移到新地址:Spring-aop /@Around增强/防止表单一分钟内多次提交 – 编程屋

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值