一、如何实现自定义注解
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,这样就可以多个实例共用一个锁。文章来源:https://www.toymoban.com/news/detail-475437.html
2.2、
未完待续…文章来源地址https://www.toymoban.com/news/detail-475437.html
到了这里,关于自定义注解,基于redis实现分布式锁的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!