java AfterReturning 处理回调

        先回顾下《AOP 基础知识》的内容。

场景:

业务场景: 在创建用户、组织,修改组织和删除的后,要回调外系统的接口。 

思考: 外系统的url的配置在数据库,根据模块和操作去匹配。 因为都是相似的操作,考虑用注解的方式去处理。因为是执行完成后再进行回调的,因此用@AfterReturnning

代码:

实体:

WebHookConfig 

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel(value = "WebHook配置")
public class WebHookConfig {
    @ApiModelProperty("webHook编码")
    private String webHookCode;

    @ApiModelProperty("webHook名称")
    private String webHookName;

    @ApiModelProperty("描述")
    private String description;

    @ApiModelProperty("webhook类型,org:create,org:update,org:delete")
    private String webHookTypes;

    @ApiModelProperty("webHook地址")
    private String webHookUrl;

    @ApiModelProperty("状态(0SA:在用|0SX:删除)")
    private String state;
}

WebHookParam 

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel(value = "WebHook参数")
public class WebHookParam {

    @ApiModelProperty("webHook类型, org:update")
    private String webHookType;

    @ApiModelProperty("数据对象")
    private Object data;

    @ApiModelProperty("是否同步调用")
    private Boolean sync;
}

声明:

WebHookCallBack 

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface WebHookCallBack {

    /**
     * 模块:对应 webhook_item 里面配置的 module值
     */
    String module() default "";

    /**
     * 操作:增删改,对应 webhook_item 里面配置的 action值
     */
    String action() default "";


    /**
     * 是否同步调用
     */
    boolean sync() default true;
}

WebHookCallBackAspect 

@Aspect
@Component
public class WebHookCallBackAspect {
    protected final Logger log = LoggerFactory.getLogger(getClass());

    @Resource
    private WebHookService webHookService;

    @Pointcut("@annotation(com.yan.studyAlone.spring.aop.annotate.after.WebHookCallBack)")
    public void callBackPointCut() {
    }

    // result是结果值
    @AfterReturning(value = "callBackPointCut()", returning = "result")
    protected Object callBackExcute(JoinPoint joinPoint, Object result) {
        log.debug("-----do AfterReturning-----");
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        WebHookCallBack annotation = method.getAnnotation(WebHookCallBack.class);
        log.debug("WebHookCallBack: {}", JSON.toJSONString(annotation));
        String module = annotation.module();
        String action = annotation.action();
        if(StringUtils.isBlank(module) || StringUtils.isBlank(action)){
            return null;
        }

        WebHookParam param = new WebHookParam();
        param.setWebHookType(module+":"+action);
        // 获取到请求参数
        Object[] args = joinPoint.getArgs();
        if(args.length == 1){
            param.setData(args[0]);
        }else{
            param.setData(args);
        }
        param.setSync(annotation.sync());
        webHookService.execute(param);
        return null;
    }
}

回调

WebHookService 

@Service
@Log4j2
public class WebHookService {
    @Resource
    private RestTemplate restTemplate;

    public Object execute(WebHookParam webHookParam) {
        // 根据 webHookParam.getWebHookType() 获取到配置
        List configs = new ArrayList<>();
        if (CollectionUtils.isEmpty(configs)) {
            return "没有查询到对应配置数据";
        }
        JSONObject param;
        for (WebHookConfig webHook : configs) {
            if (StringUtils.isEmpty(webHook.getWebHookUrl())) {
                return "配置的webhookUrl为空";
            }
            param = new JSONObject();
            param.put("webHookCode", webHook.getWebHookCode());
            param.put("webHookUrl", webHook.getWebHookUrl());
            param.put("webhookTypes", webHook.getWebHookTypes());
            param.put("data", webHookParam.getData());

            if (webHookParam.getSync()) {
                ResponseEntity responseEntity = executeSync(param);
                return responseEntity.getBody();
            } else {
                CompletableFuture> future = executeAsync(param);
                try {
                    return future.get().getBody();
                } catch (InterruptedException e) {
                    return "异步执行execute异常1" + e.getMessage();
                } catch (ExecutionException e) {
                    return "异步执行execute异常2" + e.getMessage();
                }
            }
        }
        return "成功";
    }

    public ResponseEntity executeSync(JSONObject json) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        return restTemplate.exchange(json.getString("webHookUrl"), HttpMethod.POST, new HttpEntity<>(json, headers), String.class);
    }

    public CompletableFuture> executeAsync(JSONObject json) {
        return CompletableFuture.supplyAsync(() -> executeSync(json));
    }
}

RestTemplateConfiguration 

@Configuration
public class RestTemplateConfiguration {
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }
}

这个或者启动那边加

使用例子:

OrgController 

@Api(value = "OrgController",tags = {"组织管理"})
@RestController
@RequestMapping("/org")
public class OrgController {

    @ApiOperation(value = "组织新增")
    @PostMapping("/create")
    @WebHookCallBack(module = "org", action = "create", sync = true)
    public void create(@RequestBody OrgParam param) {
        // 插入组织信息
    }
}

总结:

   如果要进行回调,内容都相似,可以考虑用注解@AfterReturnning去处理。如果实现的内容都不相同,可以考虑定义个统一回调接口,不同类去实现该方法去处理。

        

你可能感兴趣的:(spring,java,注解,AfterReturnning)