看了同事写的代码,我竟然开始默默的模仿了。。。(三)

528 阅读2分钟

「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战」。

上文中我们已经学会了用自定义参数解析器来解决参数的统一处理与验签的问题。本文我们将给出另一种解决方案,废话不多说,直接开始。

C同事的解决方案

上边 Z 同事的方案已经可以解决该问题了,但是该方案还有两个不足之处:

  • 需要每一个回调都去创建自己的 controller 层,没有一个对外的统一入口;
  • 需要在方法上添加自定义注解,侵入性比较强;

因此经过我们的商议,决定摒弃该方案,但是该方案的思想值得我们学习。接下来让我们分析一下新的解决方案:

定义业务接口类

业务接口类包含两个方法:具体业务处理的类型;业务的具体处理方法。

public interface INotifyService {
	/**
	 * 处理类型
	 */
	public String handleType();
	/**
	 * 处理具体业务
	 */
	Integer handle(String notifyBody);

}

异步通知统一入口

@AllArgsConstructor
@RestController
@RequestMapping(value = "/notify")
public class NotifyController {
	private IService service;

    @PostMapping(value = "/receive")
    public String receive(@RequestBody String body) {
        //处理通知
        Integer status = service.handle(body);
        return "success";
    }
}

在 Iservice 中做两个步骤:

  • 在 spring 启动之后,收集所有的类型为 INotifyService的类并放入map中;
  • 将参数进行处理转化,并验签处理;
private ApplicationContext applicationContext;
private Map<String,INotifyService> notifyServiceMap;

/**
 * 启动加载
 */
@PostConstruct
public void init(){
	Map<String,INotifyService> map = applicationContext.getBeansOfType(INotifyService.class);
	Collection<INotifyService> services = map.values();
	if(CollectionUtils.isEmpty(services)){
		return;
	}
	notifyServiceMap = services.stream().collect(Collectors.toMap(INotifyService::handleType, x -> x));
}

@Override
public Map<String, INotifyService> getNotifyServiceMap() {
	return notifyServiceMap;
}

@Override
public Integer handle(String body) {
	//参数处理+验签逻辑
    ......
        
	//获取具体的业务实现类
	INotifyService notifyService=notifyServiceMap.get(notifyType);
	Integer status=null;
	if(Objects.nonNull(notifyService)) {
		//执行具体业务
		try {
			status=notifyService.handle(JSON.toJSONString(requestParameter));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	//后续逻辑处理
    ......
        
	return status;
}

业务具体实现

@Service
public class NotifySignServiceImpl implements INotifyService {

    @Override
    public String handleType() {
        return "type_sign";
    }

    @Override
    @Transactional
    public Integer handle(String notifyBody) {
        //具体的业务处理
        ......
    }
}

小结

  • 此方案提供统一的异步通知入口,把公共的参数处理和验签逻辑与业务逻辑剥离。
  • 利用 java 动态加载类的特性,将实现类通过类型进行收集。
  • 利用 java 多态的特性,通过不同的实现类来处理不同的业务逻辑。

看到这,相信大家已经对这两种实现方案有了一定地理解,大家可以试着在以后的项目中应用一下,体验一把!

以上就是今天的全部内容了,如果你有不同的意见或者更好的idea,欢迎联系阿Q,添加阿Q可以加入技术交流群参与讨论呦!