自定义注解,基于redis实现分布式锁

一、如何实现自定义注解

1.1、注解的基础知识

实现自定义注解其实很简单,格式基本都差不多。也就参数可能变一变。
@Retention:取值决定了注解在什么时候生效,一般都是取运行时,也就是RetentionPolicy.RUNTIME。
@Target:决定了这个注解可以使用在哪些地方,可以取方法,字段,类等。
注解这就定义完了,不过一个注解最重要的是它实现的功能。这个时候就需要用到切面了,定义一个切面类,定义切点,切点类型就是注解,并填写所定义的注解的路径。

1.2、定义注解

package com.yumoxuan.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
}

1.3、实现切面类

package com.yumoxuan.annotation.Aspect;

import com.alibaba.fastjson.JSONObject;
import com.yumoxuan.utils.LogUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class MyAnnotationAspect {
	//定义切点,切点类型是注解,代表用到该注解的方法就会触发相关的通知(通知在后面定义)
    @Pointcut(value = "@annotation(com.yumoxuan.annotation.MyAnnotation)")
    public void pointCut(){

    }
	
	//这种方式可以直接用上面定义的注解切点,前置通知,请求进入controller之前会先调用这个方法
    @Before("pointCut()")
    public void before(JoinPoint joinPoint){
        System.out.println("前置通知开始。。。");
        System.out.println(joinPoint.toString());
        for (int i=0;i<joinPoint.getArgs().length;i++){
            System.out.println(joinPoint.getArgs()[i]);
        }
        System.out.println("前置通知结束。。。");
    }
    
    //直接写全路径注解切点,后置通知,请求进入controller并执行完之后会调用该方法。
   @After(value = "@annotation(com.yumoxuan.annotation.MyAnnotation)")
   public void after(JoinPoint joinPoint){
        System.out.println("后置通知开始");
       System.out.println(joinPoint.toString());
   }
}

1.4、实现controller类

package com.yumoxuan.controller;
import com.yumoxuan.annotation.MyAnnotation;
import com.yumoxuan.pojo.Pub;
import com.yumoxuan.pojo.Result;
import com.yumoxuan.service.PubService;
import com.yumoxuan.utils.LogUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


@RestController
public class PubController {
    @Autowired
    PubService pubService;

    @MyAnnotation
    @ResponseBody
    @RequestMapping("/getpub")
    public Result<Pub> getPub(String userName,Long userNo){
        Result res=Result.ok();
        Pub pub = pubService.getPub();
        if(Objects.nonNull(pub)){
            res.setData(pub);
        }
        return res;
    }
}

这样就定义好了一个自定义注解以及注解的逻辑。在方法上面加上注解,那么在请求进入该方法之前,会先执行前置通知,在执行完controller的方法并返回之前,会先调用后置通知。
我们看看加上注解之后的执行结果。(没加是不会有的)
在这里插入图片描述

二、基于redis实现分布式锁

之前背过分布式锁几种实现方案的八股文,但是并没有真正自己实操过。现在对AOP有了更深一点的理解,就自己来实现一遍。

2.1、分布式锁的基础知识

分布式锁是相对于普通的锁的。普通的锁在具体的方法层面去锁,单体应用情况下,各个进入的请求都只能进入到一个应用里面,也就能达到锁住方法的效果。
而分布式的系统,将一个项目部署了多个实例,通过nginx去做请求转发将请求分到各个实例。不同实例之间共用代码,共用数据库这些。比如一个请求进入A实例,获得了锁;如果继续有请求进入A实例,则会排队等待。但如果请求进入的是B实例呢?B实例的锁和A实例没有关系,那么进入B实例的请求也会获取到锁,然后进入方法。这样锁的作用就没有达到。这种情况下,就引出了分布式锁,这是专门为了解决分布式系统的并发问题的。做法是让不同的实例都能使用同一个锁。比如redis,redis内部是单线程的,把锁放在redis,这样就可以多个实例共用一个锁。

2.2、

未完待续…

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值