总览
服务模块是指针对某项业务的相关服务的集合。MCA通常分为两个子模块Service和ServiceImpl,这是equinox的最佳实践方式。
Service模块包含的是Service接口及Request Bean与Response Bean类的定义。
public interface MCXXXService extends QueryService<MCXXXRequest, MCXXXResponse> { }
ServiceImpl模块则包含ServiceImpl类实现,ServiceImpl Bean的声明,OSGI Service导出。
public class MCXXXServiceImpl extends MCQueryService<MCXXXRequest, MCXXXResponse> implements MCXXXService { ... }
服务类继承层次
查询类
查询类是一般只用于信息获取的服务。一个查询类的继承层次如下:
关于每个类的作用解释如下:
Service
定义了基本的服务接口,外部在调用服务时应当设置请求和响应上下文,也可获取请求和响应上下文。
public abstract void setRequestContext(RequestContext requestcontext); public abstract RequestContext getRequestContext(); public abstract void setResponseContext(ResponseContext responsecontext); public abstract ResponseContext getResponseContext();
请求上下文主要包含的字段都是与框架紧密联系的,与领域有关。
响应上下文则主要描述响应的具体处理情况。
AbstractService
Service的基本实现,用ThreadLocal维护请求上下文与响应上下文:
private ThreadLocal requestContextThreadLocal; private ThreadLocal responseContextThreadLocal;
QueryService
定义了查询类服务,其提供了两个接口方法prepare()与query()。这也是OSGI Service对外暴露的基本接口之一。
public abstract Object prepare(Map map); public abstract Object query(Object obj);
DataAccessQueryService
定义了数据访问的查询类服务,组合了SqlMap与TrsTemplate对象。
MCQueryService
对请求上下文与响应上下文中的数据进行提取并组装成Request Bean与Response Bean。
回调类
回调类用于双步验证,以及数据库更新操作的服务。一个回调类的继承层次如下:
整体与查询类差不多,只是核心类不同,包括CallbackService接口和MCCallbackService类。
CallbackService
定义了回调类的基本方法,也是回调类服务导出的基本接口。
MCCallbackService
组装了Request Bean与Response Bean的。提供notifySubmit()供子类重写,用于承载业务逻辑。
本质上来讲,所有RPC服务都是同步请求,命名为Callback
还是蛮怪异的,虽然其会返回调用结果。
总结
MCQueryService和MCCallbackService是用于业务流的,为WEB端提供可配置的业务逻辑映射。由于本人工作经验有限,还不能准确的评估这种模式的优缺点。但自我认为这种映射偏离了SOA的思想。
在我经历的项目中发现一个很大的问题,很多开发者将业务逻辑全部放在这些接口方法中,没有基本的方法抽取,公共服务提取,导致代码重复程度很高,逻辑也很难理清,后期维护难度大。另一方面由于糟糕的数据库设计导致无法很好的ORM映射或是懒惰原因,业务逻辑中大量使用ibatis的动态sql而非DAO层隔离,这也导致了sql的复用率很低,甚至存在安全隐患。