ESB(Enterprise Service Bus)的框架实现企业应用

简介:
 微软公司最近提供一套用于帮助企业实现ESB(Enterprise Service Bus)的框架,这套ESB框架是基于BizTalk Server的,ESB不是微软公司的专利,许多大公司例如IBM 都有自己的ESB产品,当一个企业发展到了一定规模的时候,会有很多套成熟的软件共同来支撑企业的运营,所以当一个企业的信息化建设过程,必定会需要对多个业务系统进行整合,统一管理,统一协调。同时微软公司已经成功的发布了WCF ,这样企业集成中的安全性得以解决,这也意味着在进行企业EAI的时候可以通过把各个子系统发布成WCF 的EndPoint,通过ESB框架整合起来。

       Microsoft ESB Guidance 利用BizTalk Server 强大功能去支持松耦合的消息架构,Microsoft ESB Guidance正是利用了BizTalk Server这些特性去实现企业的ESB ,BizTalk Server 支持强大发布订阅功能,也就是说Microsoft ESB Guidance是以BizTalk Server 为消息总线,所有的消息经过经过订阅者发送到BizTalk Server 的消息数据库中,然后处理转发给其他的订阅者,每个订阅者可以通过WCF 技术暴露出很多个不同端口的EndPoint。这样所有的服务都是独立的无序性的,并且是解耦的 
 
        微软通过一些列的产品Windows Server 2003, the .NET Framework 3.0, and BizTalk Server 2006作为对企业实现ESB的支撑,Microsoft ESB Guidance是基于BizTalk Server 2006一组应用,它提供以下公用的ESB组件:
·         Message routing (消息路由)
·         Message validation (消息验证)
·         Message transformation (消息转换)
·         Centralized exception management(集中的异常管理)
·         Extensible adapter framework(可扩展的适配器框架)
·         Service orchestration(服务的编制支持)
·         Business rules engine(业务规则引擎)
·         Business activity monitoring(业务活动监视)

        以我自己的异常处理经验,我通常会在UI事件处理函数或线程启动函数中截获所有的异常,然后对截获的异常作特定的处理--很多情况下,是显示一个错误信息给用户,或记录异常日志!在这“很多情况下”,我都需要做相同的工作,首先是用try...catch把UI事件处理函数或线程启动函数中的所有代码围起来,然后,可能就是MessageBox.Show(ex.Message)或其它的处理。

    大家已经想到了,这类事情正好可以使用AOP来完成。本文将在前文介绍的EsbAOP的基础上来开发一个异常关闭器方面--ExceptionCloseerAspect,该方面修饰UI操作或修饰background线程的启动函数,用于控制是否拦截被修饰的方法抛出的异常,如果拦截,则对异常进行用户自定义处理,然后关闭该异常。

    关于ExceptionCloseerAspect要注意以下几个方面:

    (1)在UI操作时或后台线程中,经常其中会访问数据库或网络,为了截获这些异常,需要在每个UI的事件处理函数中写try...catch, 如果使用ExceptionCloseerAspect,则就不用在写try-catch了,ExceptionCloseerAspect会自动帮我们把异常截获,然后关闭它。

   (2)ExceptionCloseerAspect通常用于系统结构的最上层,比如UI层、或background线程的启动函数处。而且正好这些函数的返回值为void。

   (3)用户可以通过实现IExceptionHandler自定义异常处理方案,比如记录异常日志、弹出消息框通知使用者等。

   (4)注意,一般UI从Form继承,所以无法再从ContextBoundObject继承,也就无法对其使用Aspect,所以需要把最上层的逻辑封装在一个单独的类中==》而这有助于UI与逻辑的分离!
 
    从前面的分析已经看到,线程有两种类型,一是主线程(通常为UI线程),一是后台线程,对于不同线程抛出的异常,用户可能需要作不同的处理,所以,我们使用枚举来定义线程类型:
    /// <summary>
    /// ExceptionCloseType 异常发生所在线程的类型
    /// </summary>
    public enum ExceptionHostType
    {
        NotSetted ,UIThread ,BackGroundThread
    }    
    而为了使用户有机会处理抛出的异常,我们提供了IExceptionHandler接口:
    /// <summary>
    /// IExceptionHandler 在关闭异常之前,用户可以通过自定义的IExceptionHandler来处理异常,比如记录为日志或显示错误信息给用户
    /// </summary>
    public interface IExceptionHandler
    {
        void HandleException(Exception ee ,ExceptionHostType hostType) ;
    }
    在这些基础之上,我们就可以来实现ExceptionCloseerAspect了。从前文可以知道,ExceptionCloseerAspect只需要实现IAspect接口就可以了。现在给出其实现:
public class ExceptionCloseerAspect :IAspect
    {
        public ExceptionCloseerAspect()
        {            
        }
        #region IAspect 成员
        public void PreProcess(IMethodCallMessage requestMsg, object aspectClassArgument, object aspectMethodArgument)
        {
            
        }
        public void PostProcess(IMethodCallMessage requestMsg, ref IMethodReturnMessage respond, object aspectClassArgument, object aspectMethodArgument)
        {            
            if(respond.Exception == null)
            {
                return ;
            }
            Type HandlerType = (Type)aspectClassArgument ;
            Type destType    = typeof(IExceptionHandler) ;
            if(! destType.IsAssignableFrom(HandlerType))
            {
                return ;
            }
            IExceptionHandler exceptionHandler = (IExceptionHandler)Activator.CreateInstance(HandlerType) ;
            if(aspectMethodArgument != null)
            {
                exceptionHandler.HandleException(respond.Exception ,(ExceptionHostType)aspectMethodArgument) ;
            }
            else
            {
                exceptionHandler.HandleException(respond.Exception ,ExceptionHostType.NotSetted) ;
            }
            //修改返回结果,关闭异常
            respond = new ReturnMessage(null ,requestMsg) ;
        }
        #endregion
    }
 
    上面的实现有几点需要说明:

(1)ExceptionCloseerAspect的aspectClassArgument是实现了IExceptionHandler接口的类型

(2)ExceptionCloseerAspect的aspectMethodArgument是ExceptionHostType枚举值之一。

(3)注意PostProcess方法实现的最后一句,是AOP修改了方法调用的结果,从而关闭了异常。
 
    在实现了异常关闭器之后,我们就可以来小试牛刀了。首先,我们需要实现IAspectProcessorWrap接口来把ExceptionCloseerAspect所需要的资源反应出来:
public class ExceptionClosserWrap :IAspectProcessorWrap
    {
        #region IAspectProcessorWrap 成员
        public Type AspectProcessorType
        {
            get
            {                
                return typeof(ExceptionCloseerAspect);
            }
        }
        public object AspectClassArgument
        {
            get
            {
                return typeof(ExceptionHandler) ;
            }
        }
        public EnterpriseServerBase.Aop.MultiAspect.AspectSwitcherState DefaultAspectSwitcherState
        {
            get
            {                
                return AspectSwitcherState.On;
            }
        }
        #endregion
    }
    我们还需要实现IExceptionHandler来处理异常:
public class ExceptionHandler :IExceptionHandler
    {
        #region IExceptionHandler 成员
        public void HandleException(Exception ee, ExceptionHostType hostType)
        {
            if(hostType == ExceptionHostType.UIThread)
            {
                MessageBox.Show(ee.Message + "UI Thread !") ;
            }
            if(hostType == ExceptionHostType.NotSetted)
            {
                MessageBox.Show(ee.Message + " host thread not setted !") ;
            }
            if(hostType == ExceptionHostType.BackGroundThread)
            {
                MessageBox.Show(ee.Message + " background thread !") ;
            }
        }
        #endregion
    }
    前面的代码很容易明白,异常处理只是将异常信息显示给用户。现在来看看如何使用ExceptionCloseerAspect。需要再次强调的是,ExceptionCloseerAspect通常作用于UI事件处理函数或线程启动函数。我们已一个UI事件处理函数作为例子,首先要保证UI与业务逻辑分离,所以,我将业务逻辑封装在MyBusiness类中:
    [Aspect(typeof(ExceptionClosserWrap))]
    public class MyBusiness :ContextBoundObject
    {
        [AspectSwitcher(typeof(ExceptionClosserWrap) ,true ,ExceptionHostType.UIThread)]
        public void OnButton1Click()
        {
            throw new Exception("sky test exception !") ;
        }
        [AspectSwitcher(typeof(ExceptionClosserWrap) ,true)]
        public void OnButton2Click()
        {
            throw new Exception("sky2 test exception !") ;
        }
        [AspectSwitcher(typeof(ExceptionClosserWrap) ,true ,ExceptionHostType.BackGroundThread)]
        public void SkyThread()
        {
            throw new Exception("backGround thread exception !") ;
        }
    }
     而在所有的UI事件处理函数中,都将调用MyBusiness对应的方法,如:

private void button1_Click(object sender, System.EventArgs e)
        {
            this.myBusiness.OnButton1Click() ;
        }
        private void button2_Click(object sender, System.EventArgs e)
        {
            this.myBusiness.OnButton2Click() ;
        }
        private void button3_Click(object sender, System.EventArgs e)
        {
            Thread thread = new Thread(new ThreadStart(this.myBusiness.SkyThread)) ;
            thread.Start() ;
        }
   

本文转自高阳 51CTO博客,原文链接:http://blog.51cto.com/xiaoyinnet/196447 ,如需转载请自行联系原作者

相关文章
|
监控 安全 Unix
进程回收的实现方式与注意事项:Linux C/C中的回收机制
进程回收的实现方式与注意事项:Linux C/C中的回收机制
1197 1
|
域名解析 SEO 搜索推荐
网络基础知识之————A记录和CNAME记录的区别
1、什么是域名解析? 域名解析就是国际域名或者国内域名以及中文域名等域名申请后做的到IP地址的转换过程。IP地址是网路上标识您站点的数字地址,为了简单好记,采用域名来代替ip地址标识站点地址。域名的解析工作由DNS服务器完成。
13391 1
|
2月前
|
人工智能 缓存 安全
DeepSeek V4-Flash 正式版接入 Codex,OpenAI 新模型 Astra 浮出水面,Google DeepMind 明星团队被拆
本期「周一上线」聚焦AI两大演进方向:模型加速迈向多模态与机器人,Agent则从“写代码”升级为长期协作、端到端交付与自我改进。DeepSeek V4-Flash、MiniMax H3、Gemini Robotics 2等密集发布,OpenAI Astra、Lilian Weng的RSI团队、贾扬清Intent Lab齐探AI自主进化;行业层面,AlphaFold团队拆分、字节整合飞书/豆包/火山引擎,技术与组织同步重构。
307 1
DeepSeek V4-Flash 正式版接入 Codex,OpenAI 新模型 Astra 浮出水面,Google DeepMind 明星团队被拆
|
2月前
|
JSON 自然语言处理 Java
【第二部分:大模型应用开发基础】8.Structured Output——让模型输出可被程序可靠处理的数据
Structured Output 是 Agentic AI 连接大模型与业务系统的重要基础能力。相比仅要求模型返回 JSON,它进一步通过 JSON Schema、DTO、运行时校验和业务规则校验,把概率性的模型输出转化为程序可解析、可验证、可执行的数据契约。文章结合 OpenAI 原生 Structured Outputs 与 DeepSeek JSON Output,介绍枚举、日期、金额、嵌套对象、异常修复、有限重试及 Java/TypeScript 类型映射,并强调:JSON 合法、Schema 合法并不等于业务合法,生产级 Agent 必须在结构化输出之后继续进行业务与权限校验。
216 0
【第二部分:大模型应用开发基础】8.Structured Output——让模型输出可被程序可靠处理的数据
|
3月前
|
Web App开发 前端开发 API
GPT5.6凌晨刚上线:三档模型怎么选,别把额度烧在Sol上
GPT5.6上线,推出Sol/Terra/Luna三档模型:Sol专攻复杂任务,Terra适配日常办公,Luna专注快速批量处理。搭配GPT-Live全双工语音、桌面端Work/Codex整合及限额透明化,强调“按需选模”而非盲目用强。工具越智能,越需人精准定义目标与分工。(239字)
|
3月前
|
关系型数据库 MySQL 数据安全/隐私保护
Docker 部署 Redmine:老牌开源项目管理部署实测记录
团队用 Jira、禅道、飞书项目,数据不在自己手里?Redmine 是一款开源、可自托管的项目管理与问题跟踪系统——支持 工单、甘特图、Wiki、版本库、时间跟踪,Docker Compose 双容器(Redmine + MySQL)即可跑通。浏览器打开就能建项目、派任务、看进度,数据全在你自己的服务器上。 本文带你完成一次 Redmine Docker Compose 私有化部署:镜像加速拉取、编写 docker-compose.yml、处理 3000 端口冲突、读懂启动日志,到浏览器 admin 登录、强制改密、切换中文、载入默认配置、新建第一个项目——全程零基础可跟做。
649 0
Docker 部署 Redmine:老牌开源项目管理部署实测记录
|
Linux Docker 容器
Docker 的/var/lib/docker/overlay2 占用很大,清理Docker占用的磁盘空间,迁移 /var/lib/docker 目录
Docker 的/var/lib/docker/overlay2 占用很大,清理Docker占用的磁盘空间,迁移 /var/lib/docker 目录
4189 1
|
7月前
|
芯片
掌握OVP过压保护芯片:电路设计、引脚说明及PCB板应用
过压保护OVP:指当输入达到过压保护阀值时,表现为:切断断开输出;恢复条件:输入电压低于过压保护阀值。主要功能意义:保护后级电路或芯片不被高压损坏;应用:蓝牙耳机,充电宝,等等USB输入充电口和输出高电压隔离保护电路。
|
9月前
|
人工智能
阿里云百炼优惠券更新:新客专享满20减10,按量达标返券最高50元
阿里云2026年百炼新客专享券提供满20减10元权益,有效期至1月31日,仅限首次购买指定百炼产品且订单时长1年及以内,领取后7天内使用;按量达标返券活动统计周期为2025年12月1日至2026年1月31日,按量付费累计实付金额满10元返10元券、满50元返50元券,2月14日前发券,券有效期30天,每位用户仅参与一次;
857 4

热门文章

最新文章