背景

旧版程序整合 spring,花费了一些功夫,使用起来较为繁琐,遂整合 springboot,简化一些配置。

项目搭建

一、新建 springboot 项目

  1. 使用 idea 的 Spring Initializr 创建一个 springboot 项目,名称为 learn-storm;
  2. 按需选择依赖库,我只勾选了 lombok;

二、编写 pom.xml

  1. 配置项目基本属性 properties,编写依赖库版本
<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><skipTests>true</skipTests><storm.version>1.1.0</storm.version><kafka.version>0.10.2.2</kafka.version><druid.version>1.1.18</druid.version><mybatis.version>3.4.4</mybatis.version><mybatis-spring.version>1.3.1</mybatis-spring.version><jedis.version>3.2.0</jedis.version><fastjson.version>1.2.68</fastjson.version><hutool.version>5.3.0</hutool.version></properties>
  1. 按需引入 dependency,注意使用库的版本和 storm 中自带的版本冲突,如:我使用 logback 日志框架,则需要排除 storm 中的 log4j,等等。
  2. 完整 pom.xml 如下,仅作参考
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.6.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>inti.tudan</groupId><artifactId>learn-storm</artifactId><version>1.0.0</version><name>learn-storm-with-springboot</name><description>学习 storm,整合 springboot</description><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><skipTests>true</skipTests><storm.version>1.1.0</storm.version><kafka.version>0.10.2.2</kafka.version><druid.version>1.1.18</druid.version><mybatis.version>3.4.4</mybatis.version><mybatis-spring.version>1.3.1</mybatis-spring.version><jedis.version>3.2.0</jedis.version><fastjson.version>1.2.68</fastjson.version><hutool.version>5.3.0</hutool.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-to-slf4j</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId></dependency><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-commons</artifactId></dependency><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.apache.storm</groupId><artifactId>storm-core</artifactId><version>${storm.version}</version><!-- 由于storm环境中有该jar,所以不用pack到最终的task.jar中 --><!--            <scope>provided</scope>--><exclusions><exclusion><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId></exclusion><exclusion><groupId>log4j</groupId><artifactId>log4j</artifactId></exclusion><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion><exclusion><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.apache.storm</groupId><artifactId>storm-kafka</artifactId><version>${storm.version}</version><exclusions><exclusion><groupId>log4j</groupId><artifactId>log4j</artifactId></exclusion><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka_2.10</artifactId><version>${kafka.version}</version><exclusions><exclusion><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId></exclusion><exclusion><groupId>log4j</groupId><artifactId>log4j</artifactId></exclusion><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>${kafka.version}</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>${druid.version}</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>${mybatis.version}</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>${mybatis-spring.version}</version></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>${jedis.version}</version><exclusions><exclusion><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId></exclusion><exclusion><groupId>log4j</groupId><artifactId>log4j</artifactId></exclusion><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>${hutool.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency><!-- 解析 yaml 的依赖 --><dependency><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

三、整理包结构

参考结构如下:

实现原理

Storm框架中的每个Spout和Bolt都相当于独立的应用,Strom在启动spout和bolt时提供了一个open方法(spout)和prepare方法(bolt)。我们可以把初始化Spring应用的操作放在这里,这样可以保证每个spout/bolt应用在后续执行过程中都能获取到Spring的ApplicationContext,有了ApplicationContext实例对象,Spring的所有功能就都能用上了。

  • Spout.open方法实现
@Override
public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {//启动Springboot应用SpringStormApplication.run();this.map = map;this.topologyContext = topologyContext;this.spoutOutputCollector = spoutOutputCollector;
}
  • Bolt.prepare方法实现
@Override
public void prepare(Map map, TopologyContext topologyContext, OutputCollector outputCollector) {//启动Springboot应用SpringStormApplication.run();this.map = map;this.topologyContext = topologyContext;this.outputCollector = outputCollector;
}
  • SpringStormApplication启动类
@SpringBootApplication
@ComponentScan(value = "indi.tudan.learn.storm")
@MapperScan("indi.tudan.learn.storm.core.mapper")
public class SpringStormApplication {/*** 非工程启动入口,所以不用 main 方法* 加上 synchronized 的作用是由于 storm 在启动多个 bolt 线程实例时,如果 Springboot 用到 Apollo 分布式配置,会报 ConcurrentModificationException 错误* 详见:https://github.com/ctripcorp/apollo/issues/1658** @param args 参数*/public synchronized static void run(String... args) {SpringApplication app = new SpringApplication(SpringStormApplication.class);// 我们并不需要 web servlet 功能,所以设置为 WebApplicationType.NONEapp.setWebApplicationType(WebApplicationType.NONE);// 忽略掉 banner 输出app.setBannerMode(Banner.Mode.OFF);// 忽略 Spring 启动信息日志app.setLogStartupInfo(false);app.run(args);}
}

与我们传统的Springboot应用启动入口稍微有点区别,主要禁用了web功能,看下正常的启动方式:

public class LearnStormApplication {public static void main(String... args) {// Spring ApplicationContextSpringStormApplication.run();// 提交拓扑任务SpringBeanUtils.getBean(StormTopologySubmit.class).submit();}}
  • 在spout/bolt中调用了SpringStormApplication.run方法后,我们还需要能够拿到ApplicationContext容器对象,这时候我们还需要实现ApplicationContextAware接口,写个工具类 SpringBeanUtils:
@Component
public class SpringBeanUtils implements ApplicationContextAware {/*** spring 上下文*/private static ApplicationContext applicationContext;/*** 获取 spring 上下文** @return spring 上下文* @date 2019年06月25日 16:05:26*/public static ApplicationContext getApplicationContext() {return applicationContext;}/*** 设置 spring 上下文** @param applicationContext spring 上下文* @throws BeansException 异常* @date 2019年06月25日 16:05:20*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {SpringBeanUtils.applicationContext = applicationContext;}/*** 获取已注入的 bean,返回 Object** @param beanName 已注入对象名称* @return 已注入对象* @date 2019年06月25日 16:06:04*/public static Object getBean(String beanName) {return applicationContext.getBean(beanName);}/*** 获取已注入的 bean,返回泛型** @param clazz 已注入对象的类类型对象* @param <T>   泛型* @return 已注入泛型对象* @date 2019年06月25日 16:06:33*/public static <T> T getBean(Class<T> clazz) {return applicationContext.getBean(clazz);}/*** 通过name,以及Clazz返回指定的Bean** @param beanName 已注入对象名称* @param clazz    已注入对象的类类型对象* @param <T>      泛型* @return 已注入泛型对象*/public static <T> T getBean(String beanName, Class<T> clazz) {return applicationContext.getBean(beanName, clazz);}}

通过@Component注解使得Spring在启动时能够扫描到该bean,因为BeanUtils实现了ApplicationContextAware接口,Spring会在启动成功时自动调用BeanUtils.setApplicationContext方法,将ApplicationContext对象保存到工具类的静态变量中,之后我们就可以使用BeanUtils.getBean()去获取Spring容器中的bean了。

源码下载

源码在个人 github 上
https://github.com/tudan110/learn-storm

参考资料

Storm框架:Storm整合springboot

学习 storm,整合 springboot相关推荐

  1. Storm整合Springboot

    Storm是一个分布式的实时的流式计算框架. Storm运行有两种模式,分别是local与remote. Storm的local就是单进程模式(运行在单一的JVM),local模式storm(注:下文 ...

  2. SpringBoot学习笔记(16)----SpringBoot整合Swagger2

    Swagger 是一个规范和完整的框架,用于生成,描述,调用和可视化RESTful风格的web服务 http://swagger.io Springfox的前身是swagger-springmvc,是 ...

  3. SpringBoot基础学习之整合Swagger框架(上篇)

    前言: 小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师. 这个SpringB ...

  4. MongoDB的学习-安装与springboot的整合

    mongoDB的学习: 1.mongodb 安装及使用 mongodb 安装及使用__mongodb安装使用 MongoDB社区下载 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上 ...

  5. Mbatis-Plus整合springboot详细学习笔记

    文章目录 Mbatis-Plus 学习笔记 一.基本架构 二.查询方法 2.1.构造条件查询 2.2.嵌入sql查询 2.3.分组查询 2.4.只返回一条数据 2.5.返回指定列数据 2.6.在字段上 ...

  6. SpringBoot基础学习之整合SpringSercurity框架

    前言: 小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师. 这个SpringB ...

  7. Shiro框架学习笔记、整合Springboot、redis缓存

    本笔记基于B站UP主不良人编程 目录 1.权限的管理 1.1什么是权限管理 1.2什么是身份认证 1.3什么是授权 2.什么是Shiro 3.Shiro的核心架构 3.1 S核心内容 4.shiro中 ...

  8. Nebula Graph学习篇1_基础概念、初步使用、整合SpringBoot使用

    目录 一.基础概念 图数据库的概念 适用场景 数据模型 路径 点的VID 架构 二.初步使用 Windows安装Nebula-Graph服务 Nebula Console 连接 Nebula-Grap ...

  9. MongoDB入门学习(一)简介与基本操作、整合SpringBoot集合操作、整合SpringBoot文档操作

    文章目录 1. 简介 1.1 NoSQL和MongoDB 1.2 MongoDB特点 1.2.1 MongoDB 技术优势 1.2.2 Json 模型快速特性 1.3 MongoDB 应用场景 1.4 ...

  10. 使用Gradle整合SpringBoot+Vue.js-开发调试与打包

    为什么80%的码农都做不了架构师?>>>    非常感谢两位作者: kevinz分享的文章<springboot+gradle+vue+webpack 组合使用> 首席卖 ...

最新文章

  1. 怎样成为一名优秀的系统工程师
  2. BZOJ 1568 李超线段树
  3. VTK:网格质量用法实战
  4. Mysql 的表级锁和行级锁
  5. WPF——专用枚举器ListBox和ComboBox
  6. 如何快速解决腿抽筋?
  7. strict standards php报错,Bigcommerce:PHP版本升级错误解决办法_PHP教程
  8. Atitit 开发效率补充哦哦那个、、 目录 1. 架构方法上选择快速开发的架构 1 2. 编程方法上选择快速的编程范式和编程方法 1 3. 开发方法论上需要快速的方法 2 1.架构方法上选择快速
  9. SQL Server 启动错误 系统找不到指定的文件/路径
  10. 完全掌握加密解密实战超级手册
  11. Eclipse 安装离线版 Jrebel
  12. selenium+chromedriver实现自动填写问卷星问卷
  13. 大家好,我是浪啦啦啦啦啦!
  14. latex footnote numbering
  15. 盗版升级win10仍是盗版
  16. 跨专业考研应该怎么做?
  17. Linux Ubuntu系统设置成中文语言
  18. 2021年11月逆向练习
  19. 保利紫山开启湛江城市墅居新纪元
  20. 学计算机用啥u盘好,U盘制作工具哪个好用?2020U盘制作工具推荐

热门文章

  1. io_uring 新异步 IO 机制,性能提升超 150%,堪比 SPDK
  2. ajax中sy,黑马eesy_15 Vue:vue语法和生命周期与ajax异步请求
  3. 【图像加噪】基于matlab多种噪声图像加噪(含信息熵)【含Matlab源码 1837期】
  4. 【路径规划】基于matlab人工蜂群优化粒子群算法求解最短路径规划问题【含Matlab源码 124期】
  5. 【滤波器设计】基于matlab GUI窗函数法高通+低通+带通带阻FIR滤波器设计【含Matlab源码 072期】
  6. python将一个文本文件复制到另一个文件中_使用Python逐行从一个文本文件复制到另一个文本文件...
  7. 强化学习与环境不确定_不确定性意识强化学习
  8. php检测http状态码,分享一段php判断url http状态码的代码
  9. 计算机网络-Postman测试http的get和post方法
  10. 问题1:VS2017:找不到 Windows SDK 版本10.0.17134.0