在Storm中IBasicBolt的主要作用是为用户提供一种更为简单的Bolt编写方式,更为简单体现在Storm框架本身帮你处理了所发出消息的Ack、Fail和Anchor操作,而这部分操作是由执行器BasicBoltExecutor 实现的。
下面我们看一下BasicBoltExecutor的源码:

/*** BasicBoltExecutor实现了IRichBolt接口* 在该类中持有一个IBasicBolt成员变量用于调用转发* 说明:* 该类是基于装饰模式实现的.*/
public class BasicBoltExecutor implements IRichBolt {public static Logger LOG = LoggerFactory.getLogger(BasicBoltExecutor.class);    //持有IBasicBolt类型的变量private IBasicBolt _bolt;//定义了成员变量_collectorprivate transient BasicOutputCollector _collector;public BasicBoltExecutor(IBasicBolt bolt) {_bolt = bolt;}/*** 实现declareOutputFields方法,但它实际上是* _bolt调用declareOutputFields方法*/public void declareOutputFields(OutputFieldsDeclarer declarer) {_bolt.declareOutputFields(declarer);}/*** 实现prepare方法,* 实际上是调用_bolt的prepare方法,* 并实例化BasicOutputCollector*/public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {_bolt.prepare(stormConf, context);_collector = new BasicOutputCollector(collector);}/*** 实现execute方法*/public void execute(Tuple input) {//设置运行器上下文,//它表示经execute方法发送出去的消息都是由输入消息产生的,//即输出的消息都将标记为输入消息所衍生出来的消息,//这是使用IBasicBolt实现消息跟踪的重要一环_collector.setContext(input);try {//调用_bolt的execute方法_bolt.execute(input, _collector);//对输入的消息进行Ack操作.//这一步意味着基于当前输入消息的处理和衍生消息的发送已经完成,//这时就可以对该消息进行Ack操作了._collector.getOutputter().ack(input);} catch(FailedException e) {//Storm捕获所有的FailedException,并对输入的消息进行Fail操作。//如果捕获的异常为ReportedFailedException的实例,//则调用reportError回调方法,给用户一个机会去处理异常//FailedException是Storm定义的一种基本异常,用来进行消息的失败重发等操作,//并不会导致Topology运行停止if(e instanceof ReportedFailedException) {_collector.reportError(e);}_collector.getOutputter().fail(input);}}public void cleanup() {_bolt.cleanup();}public Map<String, Object> getComponentConfiguration() {return _bolt.getComponentConfiguration();}
}

先说说装饰模式的结构,装饰模式UML类图如图所示:

如上图所示,装饰模式的角色构成:
(1)抽象组件角色-Component:给出一个抽象接口,以规范或约束准备接收附加职责的对象.
(2)具体组件对象-ConcreteComponent:实现了组件对象的接口,通常是被装饰器装饰的原始对象.
(3)装饰角色-Decorator:所有装饰器的抽象父类,需要定义一个与组件接口一致的接口,
并持有一个Component对象,其实就是持有被装饰的对象
(4)具体装饰对象-ConcreteDecorator:实际的装饰器对象,负责给组件对象添加附加的功能

现在举一个常见的例子(冲咖啡)来说明一下。
我敲代码困了,想冲一杯咖啡来提提神,但我怕咖啡苦,便向咖啡里加点糖(用糖装饰一番),喝着喝着觉得没有牛奶香,边往咖啡里到点牛奶(用牛奶装饰咖啡一番),这整个过程便可看成装饰模式.
代码:
1.先定义一个接口用来约束职责对象

/*** Component  * 抽象构建角色,* 约束或规范准备接收附加责任的对象*/
public interface Component {public void operation();
}

2.实现组件对象的接口,它是被装饰器装饰的原始对象(这里是咖啡)

/*** ConcreteComponent  * 接收附加责任*/
public class ConcreteComponent implements Component {@Overridepublic void operation() {System.out.println("的咖啡");}
}

3.定义装饰器

/*** Decorator装饰角色 */
public abstract class Decorator implements Component {//持有一个构建对象的实例private Component component;public Decorator(Component component){this.component=component;}@Overridepublic void operation() {component.operation();}
}

4.实现加糖装饰器和加牛奶装饰器

/** * ConcreteDecorator1* 加糖装饰器*/
public class ConcreteDecorator1 extends Decorator {public ConcreteDecorator1(Component component) {super(component);// TODO Auto-generated constructor stub}public void operation(){System.out.print("加糖");super.operation();}
}
/*** ConcreteDecorator2   * 加奶装饰器*/
public class ConcreteDecorator2 extends Decorator {public ConcreteDecorator2(Component component) {super(component);// TODO Auto-generated constructor stub}public void operation(){System.out.print("加奶");super.operation();}
}

5.测试

public class Test {public static void main(String[] args) {// TODO Auto-generated method stubComponent component=new ConcreteComponent();Decorator decorator1=new ConcreteDecorator2(component);Decorator decorator2=new ConcreteDecorator1(decorator1);decorator2.operation();}
}

6.测试结果

加糖加奶的咖啡

jdk中也大量使用装饰模式。比如Java流接口中输出流部分
OutputStream就相当于装饰模式中的Component;
FileOutputStream、ObjectOutputStream这几个对象直接继承了OutputStream,
还有一些对象直接继承OutputStream对象,比如:ByteArrayOutputStream、PipedOutputStream等.这些对象相当于装饰模式中的ConcreteComponent,是可以被装饰器装饰的对象.
FilterOutputStream相当于装饰模式中的Decorator,而他的子类DataOutputStream、BufferedOutputStream就相当于装饰模式中的ConcreteDecorator。FilterOutputStream和它的子类对象的构造器都是传入组件OutputStream。对照上述将的装饰模式的结构图,由此可见这部分类的设计完全采用装饰模式.
同理输入流部分也类似。

注:学习李明老师Storm源码分析的笔记整理。
欢迎关注下面二维码进行技术交流:

JStorm与Storm源码分析(七)--BasicBoltExecutor与装饰模式相关推荐

  1. JStorm与Storm源码分析(一)--nimbus-data

    Nimbus里定义了一些共享数据结构,比如nimbus-data. nimbus-data结构里定义了很多公用的数据,请看下面代码: (defn nimbus-data [conf inimbus]( ...

  2. JStorm与Storm源码分析(八)--计时器工具-mk-timer

    Storm使用计时器线程来处理一些周期性调度事件. 与计时器相关的操作主要有:创建计时器线程.查看线程是否活跃.向线程中加入新的待调度事件.取消计时器线程 mk-timer方法用于创建一个计时器线程. ...

  3. JStorm与Storm源码分析(六)--收集器 IOutputCollector 、OutputCollector

    在Storm中,多个地方使用了IOutputCollector收集器接口,收集器OutputCollector的接口就是IOutputCollector.所以有必要对接口IOutputCollecto ...

  4. JStorm与Storm源码分析(三)--Scheduler,调度器

    Scheduler作为Storm的调度器,负责为Topology分配可用资源. Storm提供了IScheduler接口,用户可以通过实现该接口来自定义Scheduler. 其定义如下: public ...

  5. JStorm与Storm源码分析(二)--任务分配,assignment

    mk-assignments主要功能就是产生Executor与节点+端口的对应关系,将Executor分配到某个节点的某个端口上,以及进行相应的调度处理.代码注释如下: ;;参数nimbus为nimb ...

  6. JStorm与Storm源码分析(四)--均衡调度器,EvenScheduler

    EvenScheduler同DefaultScheduler一样,同样实现了IScheduler接口,  由下面代码可以看出: (ns backtype.storm.scheduler.EvenSch ...

  7. JStorm与Storm源码分析(二)--任务分配,assignmen

    mk-assignments主要功能就是产生Executor与节点+端口的对应关系,将Executor分配到某个节点的某个端口上,以及进行相应的调度处理.代码注释如下: 1 ;;参数nimbus为ni ...

  8. JStorm与Storm源码分析(五)--SpoutOutputCollector与代理模式

    本文主要是解析SpoutOutputCollector源码,顺便分析该类中所涉及的设计模式–代理模式. 首先介绍一下Spout输出收集器接口–ISpoutOutputCollector,该接口主要声明 ...

  9. Storm源码分析之四: Trident源码分析

    Storm源码分析之四: Trident源码分析 @(STORM)[storm] Storm源码分析之四 Trident源码分析 一概述 0小结 1简介 2关键类 1Spout的创建 2spout的消 ...

最新文章

  1. Java虚拟机学习(8):查看JVM参数及值的命令行工具
  2. 三体智能革命_《三体》之人类的科技文明发展历史其实很诡异
  3. VMware演示手机虚拟化
  4. springmvc新建拦截器
  5. HDU 5730——Shell Necklace
  6. python logging模块的作用及应用场景_Python logging模块原理解析及应用
  7. springsession分布式登录被覆盖_拉勾 分布式 学习小结
  8. MyBatis复习(三):MyBatis核心对象SqlSessionFactory和SqlSession
  9. 【LOJ#2507】[CEOI2011]Matching(KMP,树状数组)
  10. 在计算机网络中使用modem时它的功能是,在计算机网络中使用MODEM时,它的功能是____。...
  11. 直接让web服务运行在80端不行吗,为什么要用nginx反向代理?
  12. 上周的工作总结和下周的学习安排
  13. arcgis 只能查看指定行政区域_[教程】Arcgis进阶:统计分析
  14. RFID固定资产盘点系统给企业带来哪些便利?
  15. BTN7970在直流电机驱动系统中的应用
  16. java解析txt文本文件_java读取文本文件内容方法详解,java如何读取txt文件?
  17. 我会安静的忘记你:伤感爱情空间日志
  18. bcg库使用心得两则
  19. windows运行程序命令
  20. Spring mvc Controller间跳转/重定向/传参

热门文章

  1. 解决element-ui表头错位的问题
  2. WebSocket部署服务器外网无法连接解决方案
  3. 如何更改微调器的文字大小和文字颜色?
  4. 在什么情况下我应该使用malloc和/或new?
  5. 最大子序和的golang实现
  6. 补第四周作业总结——8 puzzle
  7. C语言:指针的几种形式
  8. VMWare虚拟机连接方式
  9. VS013的单元测试去哪里了
  10. 探索--是测试的必须品