Spring boot 自定义注解+AOP实现互斥锁

需求

随着业务量的不断增长,并发问题时有出现,要解决这些问题需要引入锁机制

同步关键字解决方案

最初在方法上加同步关键字synchronized,这种方式只能限制同一个类中的方法,不同类中的方法仍然可以并发
那么可以使用同步代码块解决该问题,定义一个公共的锁,然后在需要同步的方法开始和结束加上同步代码块,这样就能解决问题了,但是这种写法很繁琐,需要每个方法头尾去加代码,由此想到了AOP和自定义注解

定义锁注解

1
2
3
4
5
6
7
8
import java.lang.annotation.*;

@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ServiceLock {
String description() default "service lock";
}

AOP切面

在Service层定义切面,方法执行前后分别加锁和解锁,使用时需要同步的方法加上@ServiceLock

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* 同步锁 AOP
* https://docs.spring.io/spring/docs/4.3.14.RELEASE/spring-framework-reference/htmlsingle/#transaction-declarative-annotations
* https://docs.spring.io/spring/docs/4.3.14.RELEASE/javadoc-api/
*/
@Component
@Scope
@Aspect
@Order(1)
public class LockAspect {
/**
* 互斥锁 参数默认false,不公平锁
*/
private static Lock lock = new ReentrantLock(true);

/**
* Service层切点 用于记录错误日志
*/
@Pointcut("@annotation(com.xxx.xxx.service.lock.ServiceLock)")
public void lockAspect() {

}

@Around("lockAspect()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
lock.lock();
Object obj;
try {
obj = joinPoint.proceed();
} finally {
lock.unlock();
}
return obj;
}
}

文章目录
  1. 1. 需求
    1. 1.1. 同步关键字解决方案
    2. 1.2. 定义锁注解
    3. 1.3. AOP切面