--- title: Spring boot 自定义注解+AOP实现互斥锁 date: 2019-05-21 15:48:36 description: Spring boot 自定义注解+AOP实现互斥锁 categories: [技术总结] tags: [Java, Spring boot] --- ## 需求 随着业务量的不断增长,并发问题时有出现,要解决这些问题需要引入锁机制 ### 同步关键字解决方案 最初在方法上加同步关键字`synchronized`,这种方式只能限制同一个类中的方法,不同类中的方法仍然可以并发 那么可以使用同步代码块解决该问题,定义一个公共的锁,然后在需要同步的方法开始和结束加上同步代码块,这样就能解决问题了,但是这种写法很繁琐,需要每个方法头尾去加代码,由此想到了AOP和自定义注解 ### 定义锁注解 ```java import java.lang.annotation.*; @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ServiceLock { String description() default "service lock"; } ``` ### AOP切面 在Service层定义切面,方法执行前后分别加锁和解锁,使用时需要同步的方法加上`@ServiceLock` ```java /** * 同步锁 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; } } ```