从零手写并发框架(四)异步转同步 springboot 整合

序言上一节我们学习了异步查询转同步的 7 种实现方式 , 今天我们就来学习一下 , 如何对其进行封装 , 使其成为一个更加便于使用的工具 。
思维导图如下:
从零手写并发框架(四)异步转同步 springboot 整合文章插图
异步转同步
本节主要介绍注解框架如何整合 spring 和 springboot 。
让我们的框架使用更加便利 。
拓展阅读java 手写并发框架(一)异步查询转同步的 7 种实现方式
java 手写并发框架(二)异步转同步框架封装锁策略
java 手写并发框架(三)异步转同步框架注解和字节码增强
java 手写并发框架(四)异步转同步框架spring整合
整合思路spring 整合其实整体的实现类似于 spring 的 @Retry 注解 。
(1)在锁同步方法上使用对应的注解 @Sync
(2)在异步回调方法上使用注解 @SyncCallback
(3)通过定义 aop 切面 , 实现拦截调用
springboot 整合通过 spring-boot-starter 特性 , 实现与 springboot 的整合
spring 整合实现注解定义我们定义 @EnableSync 注解 , 用于声明启用 Sync 同步功能 。
这个用过 spring 框架的 , 应该见过很多类似的注解 , 比如 @EnableAsync @EnableRetry 等等 。
package com.github.houbb.sync.spring.annotation;import com.github.houbb.sync.spring.config.SyncAopConfig;import org.springframework.context.annotation.EnableAspectJAutoProxy;import org.springframework.context.annotation.Import;import java.lang.annotation.*;/** * 启用自动日志注解 * @author binbin.hou * @since 0.0.2 */@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(SyncAopConfig.class)@EnableAspectJAutoProxypublic @interface EnableSync {}这里导入了一个 SyncAopConfig 配置 。
实现如下:
import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;/** * 自动 sync aop 配置 * * @author binbin.hou * @since 0.0.2 */@Configuration@ComponentScan(basePackages = "com.github.houbb.sync.spring")public class SyncAopConfig {}主要用于指定需要扫描的包 。
aop 核心实现package com.github.houbb.sync.spring.aop;import com.github.houbb.aop.spring.util.SpringAopUtil;import com.github.houbb.sync.api.annotation.Sync;import com.github.houbb.sync.api.annotation.SyncCallback;import com.github.houbb.sync.api.api.ISyncContext;import com.github.houbb.sync.core.bs.SyncBs;import com.github.houbb.sync.spring.context.SpringAopSyncContext;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.springframework.context.annotation.EnableAspectJAutoProxy;import org.springframework.core.annotation.AnnotationUtils;import org.springframework.stereotype.Component;import java.lang.reflect.Method;/** * 这是一种写法 * @author binbin.hou * @since 0.0.2 */@Aspect@Component@EnableAspectJAutoProxypublic class SyncAop {/**** 切面方法:** (1)扫描所有的共有方法**execution(public * *(..))* ** 问题:切面太大 , 废弃 。* 使用扫描注解的方式替代 。** (2)扫描指定注解的方式** 其实可以在 aop 中直接获取到注解信息 , 暂时先不调整 。* 暂时先不添加 public 的限定** (3)直接改成注解的优缺点:* 优点:减少了 aop 的切面访问* 缺点:弱化了注解的特性 , 本来是只要指定的注解即可 ,** 不过考虑到使用者的熟练度 , 如果用户知道了自定义注解 , 自定义 aop 应该也不是问题 。*/@Pointcut("@within(com.github.houbb.sync.api.annotation.Sync)" +"|| @within(com.github.houbb.sync.api.annotation.SyncCallback)" +"|| @annotation(com.github.houbb.sync.api.annotation.Sync)" +"|| @annotation(com.github.houbb.sync.api.annotation.SyncCallback)")public void syncPointcut() {}/*** 执行核心方法** 相当于 MethodInterceptor** @param point 切点* @return 结果* @throws Throwable 异常信息* @since 0.0.2*/@Around("syncPointcut()")public Object around(ProceedingJoinPoint point) throws Throwable {Method method = SpringAopUtil.getCurrentMethod(point);Sync sync = AnnotationUtils.getAnnotation(method, Sync.class);SyncCallback callback = AnnotationUtils.getAnnotation(method, SyncCallback.class);ISyncContext context = SpringAopSyncContext.newInstance().method(method).sync(sync).callback(callback).point(point);return SyncBs.newInstance().syncContext(context).execute();}}


推荐阅读