一. 写在前面
源码看的多了,就会感觉到很多架构都有相似的地方,许多操作都有其通用性。就像框架中的一些组件,以及他们承担的责任,都有相似的地方,这篇博客就来分析一下组件中通用类的作用。
二. 组件中通用功能类分析
首先我们看一下现在很流行的 Seata 框架,它的全局事务的控制是如何做到的:

1 .如果想让某个事务在上下文中传播,必然要有一个唯一的事务身份,即transactionId,此时还要有一个事务身份的管理容器,即RootContext。
2.事务容身的容器有了,当事务执行的时候,会有各种状态,比如 rollback 和 commit ,这时需要一个GlobalStatus用来定义事务的状态。
3.我们开始定义一个事务,在上下文中传播,并且根据业务的需要改变自身状态。
比如:Seata的全局事务TM开启时,分支事务 RM 需要注册到全局事务上,那就需要定义两个事务模型即:全局事务GlobalSession 和 分支事务BranchSession。
4.如果追求很好的扩展性,可以把流程的处理抽象出来,封装成一个 template 文件 ,就像 Seata AT模式 在进行sql解析时,有固定的几个步骤:
解析sql–>beforeImage–>业务sql–>afterImage–>生成行锁–>undoLog入库
这几个步骤可以抽象出来,写在一个方法中。当然,这些操作其实有的是在数据库层面做的,这里只是举例说明一下。
有了以上四个功能性类,client 端的事务处理就很清晰并且立体了,有容器,有流程,有状态,有具体的事务。
三. 服务器中通用组件分析
java中使用最多的服务器毫无疑问是Tomcat,下图是Tomcat中 Container组件架构图:

这里容器就是Container,Connector表示环境,Endpoint中封装了处理流程,每个请求进来都有对应的Connector进行处理,看得见的操作都进行流程化,非常的清晰。
四. 总结
其实不只是中间件架构中可以使用这些标准化的类,业务框架也可以。
就比如可以抽象出来一个 RequestContext,第一次在业务中获取参数的时候,解析request中参数,并存储到ThreadLocal 中,后续多次获取参数就可以直接取 threadlocal中的,然后在 Controller 或者 Service 中使用。
还可以把业务操作人的身份在拦截器中封装到 ExcutionContext 中 ,后续controller和service之间可以不用传递,使用context环境就可以直接取,这样封装可以让整个框架变得立体,而不仅仅是一串流程传递下来。
最后可以封装一个全局异常处理,异常可以分为业务异常和参数解析异常等等,使用springmvc提供的异常拦截器,在请求处理完成后判断是否有异常,如果有,封装异常信息并返回。这样业务处理就变得简单,参数验证失败的时候,直接抛异常就行,不用再进行返回值的封装。
以上几个方式,可以让业务代码变得简洁,业务代码只处理业务。凯撒的归凯撒。
.
附上几篇不错的Seata解析博客:

1477

被折叠的 条评论
为什么被折叠?



