写点什么

我为何停止使用 Spring

  • 2013-12-26
  • 本文字数:2466 字

    阅读完需:约 8 分钟

Johannes Brodwall 是一位程序员、解决方案架构师、用户组与会议组织者、会议演讲者与布道师。Johannes 一直在不遗余力地将敏捷原则应用到大型软件项目中,不过他真正感兴趣的是与全世界的程序员分享更多关于编程的有趣经验。目前,Johannes 就职于 Exilesoft,担任首席科学家一职。近日,Johannes 撰写了一篇关于他为何停止使用Spring 的文章,在程序员群体中引起了很大的反响。

我之前发表的一篇题为谦卑的架构师的文章引起了很多争论,特别是Spring 与依赖注入框架这个话题,这次我打算来谈谈为什么我要停止Spring。我是挪威最早采用Spring 框架的一批人。我们在开发一个大型系统时最后不得不考虑诸如如何重用XML 配置文件的各种不同机制等问题。最后,这演变成了@Autowire 与component-scan,这种方式解决了大量配置文件的难题,不过却降低了人们了解全部源代码的能力,这直接导致开发者被限制在应用中非常小的部分代码中。随着应用变得越来越复杂,文化、工具、文档等东西导致开发者们不得不在一个个不必要的层次上构建另外一些不必要的层次。

不久之后,我尝试在不使用依赖注入框架的情况下来构建应用,不过这引发了另外一些问题,那就是何时该使用“new”呢、何时使用setter 或是构造器参数呢,哪种类型适合作为依赖呢、哪些东西导致了对基础设施的耦合呢。

根据直觉我发现DI 框架确实能够帮助我改善设计,不过与此同时,我还发现在离开容器时,解决方案变得更小(这很棒!)、理解起来更简单,并且易于测试。这让我感到进退维谷,我发现使用容器的代价是非常高的,它会不断增加复杂性与规模,同时会降低一致性。不过话又说回来,它教会了我一些更棒的设计技巧。

总的来说,我个人认为一致、小型的系统要比那些为了解耦而解耦的系统更有价值。一致性与解耦是对立的,我站在一致性这一边。同时,我发现依赖注入文化对重用性有更强的偏爱,不过重用会引入耦合。如果模块A 重用了模块B,那么我们就说模块A 与模块B 是耦合的。模块B 中的变化可能会对模块A 产生更好(修复Bug)或是更糟(引入新的Bug)的影响结果。如果重用所带来的好处更多,那就值得使用;否则就不值得。因此,重用与解耦是对立的两个方面,我自己更偏向于解耦。如果出现冲突,我个人认为优先级应该是一致性大于解耦,解耦大于重用性,而Spring 的基因似乎与此相反。

Johannes 的文章发布后,旋即引起了程序员社区的激烈讨论,有些讨论也很有意思,下面摘录几篇:

Marc Stock 说到:

如果使用 Spring 的依赖注入增加了系统的复杂性,那么问题的症结在于你自己。我使用 Spring 有好几年的经历了,它总是让事情变得更棒和更整洁。我不敢说所有的 Spring 项目都是这样,不过对于依赖注入来说绝对没错。也就是说,我发现有很多使用 Spring 的方式值得商榷,事实上他们做的很多事情都是不必要的(不过他们却并不这么认为)。如果你能举出 Spring 依赖注入会引起混乱的例子,我愿意拭目以待。

Johannes Brodwall 说到:

文章的质疑很不错。我来举个简单的例子,假如一个系统有很多层次,所有东西都被加上了 @Autowire 与 component-scan。我尝试实例化其中的某些服务,不过却缺少依赖。最后只能将所有的依赖加进来来实例化测试中所需的一个简单服务,因为查找存在哪些依赖、应该使用哪些依赖来作为模拟花费了我大量的时间。

Hendy Irawan 说到:

文中提到“同时,我发现依赖注入文化对重用性有更强的偏爱,不过重用会引入耦合。如果模块 A 重用了模块 B,那么我们就说模块 A 与模块 B 是耦合的”。这里需要对“模块”做一些澄清。接口会帮助我们更好地理解。在重用时,使用的是 Spring、CDI 还是你自己的什么东西并不重要。你提到“Spring 文化”,是真的么?举个例子,使用(c3p0)数据源与 PlatformTransactionManager(JpaTransactionManager)来配置一个 JPA EntityManager(FactoryBean)。这里会有大量的重用,不过解耦性却很不错。你可以将 JPA 切换到 Hibernate,也可以将 c3p0 却换到其他数据源,还可以将 TransactionManager 切换到 Hibernate 或是 JTA 的。 你讨厌 XML 配置,也讨厌 @Autowired,不过配置总归是要有的。如果喜欢 set 或是 new 的方式,那么你可以使用注解,文中并没有提及这一点。如果使用的是 CDI,那么讨厌 @Autowired/@Inject 有情可原,不过这是 Spring,你有很多选择。根据我的经验,对于后端服务绑定使用注解配置,对于 UI 组件使用 @Inject 会更好一些。我们也不使用 XML,你可以尝试一下这种方式。

Manuel Rascioni 说到:

这几天我一直在思考是否该使用 Spring,现在我觉得使用是值得的。看看整个(Web)应用,你需要这些东西:一个依赖注入管理系统、一个持久化框架、在各个层之间转换对象的东西、一个安全框架与一个 AOP 系统(管理事务、安全等东西)。你有多种选择,也可以自己创建。如果使用现有的,那需要注意的就是不同框架的集成;如果自己创建,那就需要自己编写大量代码。我的经历告诉我使用 Spring 可以很好地解决这些问题。它不仅仅是个依赖注入框架,还是一套完整的框架生态系统,可以实现组件之间的解耦,同时又很好地实现了这些框架之间的集成。对于测试来说,我使用 mock 框架进行单元测试,而没有使用 Spring(对于单元测试来说它太慢了)。对于集成测试来说,我们需要使用 Spring 配置文件。因此,根据我的经验来看,使用 Spring 是值得的。关于文中提到的耦合,如果模块 C 需要模块 A 的一些东西,你是怎么解决的呢?难道是编写一个新的模块,然后复制模块 A 么?这完全违背了 DRY 原则吧。

各位 InfoQ 读者,你是如何看待文中的观点以及各个评论的看法的呢?Spring 从诞生到现在已经有很多年了,从最早的依赖注入与面向方面编程到现在的一站式框架体系,Spring 本身也变得越来越庞大了,但同时功能也是越来越强大。特别是前不久刚刚发布的 Spring 4.0 更是增加了不少令人激动的新特性,那么在你的项目与系统中是否使用到了 Spring 呢?你觉得 Spring 带给你的好处与它本身的缺陷相比如何呢?换句话说,Spring 框架的性价比高么?欢迎发表评论与大家一同分享你的观点与看法。

2013-12-26 11:2210835
用户头像

发布了 88 篇内容, 共 264.0 次阅读, 收获喜欢 8 次。

关注

评论

发布
暂无评论
发现更多内容

UI自动化的稳定性和效率

QE_LAB

自动化测试 UI自动化测试 appium

Spring框架中的线程池

demo123567

spring 线程池

CQ 社区版 v2.1.0 发布 | 新增数据发布变更、内置脱敏规则等功能

BinTools图尔兹

运维 数据库管理 数据脱敏 CloudQuery 数据变更

HarmonyOS 极客马拉松2023 正式启动,诚邀极客们用键盘码出无限可能!

HarmonyOS开发者

HarmonyOS

CFlow:从DevOps到BizDevOps,价值流管理是必然的趋势

嘉为蓝鲸

DevOps 价值流 嘉为蓝鲸 VSM

Python自动化测试的配置层实现方式对标与落地 | 京东云技术团队

京东科技开发者

Python 自动化测试 配置文件 企业号 6 月 PK 榜

Docker 与 Kubernetes:打造高效微服务架构的最佳实践

xfgg

Java Docker Kubernetes 6 月 优质更文活动

vivo 帐号服务稳定性建设之路-平台产品系列06

vivo互联网技术

帐号 服务稳定性 架构优化

首添机密计算创新成果!龙蜥首获 ACM SIGSOFT 杰出论文奖

OpenAnolis小助手

云原生 龙蜥社区 sig 机密计算 ICSE

共建、共享开源EDA核心共性技术框架|2023开放原子全球开源峰会开源EDA分论坛成功举办

开放原子开源基金会

开源 开放原子全球开源峰会 开放原子 开源EDA

当 Rokid 遇上函数计算

Serverless Devs

C语言代码封装MQTT协议报文,了解MQTT协议通信过程

DS小龙哥

6 月 优质更文活动

洞察开源代码平台“创新力”|2023开放原子全球开源峰会开源协作平台分论坛成功举办

开放原子开源基金会

开源 开放原子全球开源峰会 开放原子 开源协作平台

玺璐传媒——连续多年获得中央电视台广告一级代理资质

科技热闻

IT服务台智能助手,真的靠谱吗?

嘉为蓝鲸

智能助手 GPT IT服务 ChatGPT

WeOpsV4.1重磅出击,日志监控功能横空出世!

嘉为蓝鲸

运维 日志 weops 嘉为蓝鲸

原点安全助力金融机构消费者个人信息保护合规

原点安全

数据安全 金融机构 消费者个人信息保护

广东省高校人工智能产教融合院长研讨会召开,校企协同探索AI教育新范式

飞桨PaddlePaddle

一行代码将SAP CDS view数据以ALV的方式输出

汪子熙

abap Netweaver 思爱普 6 月 优质更文活动

iOS 单元测试之常用框架 OCMock 详解 | 京东云技术团队

京东科技开发者

ios 测试 单元测试 Mock 企业号 6 月 PK 榜

「有问必答」Go如何优雅的对时间进行格式化?

王中阳Go

高效工作 学习方法 面试题 Go 语言 6 月 优质更文活动

HTTP请求:requests模块基础使用必知必会 | 京东云技术团队

京东科技开发者

Python HTTP请求 requests 企业号 6 月 PK 榜

开源教育决定未来|2023开放原子全球开源峰会开源教育与人才分论坛成功召开

开放原子开源基金会

开源 开放原子全球开源峰会 开放原子 开源教育与人才

3个方法,产品迭代延期率降为0?

嘉为蓝鲸

DevOps 持续集成 研发迭代

给你的 ABAP 对象打上标签(Tag)

汪子熙

SAP abap Netweaver 思爱普 6 月 优质更文活动

自动化回归测试平台 AREX 的 Mock 实现原理

AREX 中文社区

Java Mock测试框架 流量回放

轻松解决Kafka数据流丢失:提升数据完整性和可靠性

xfgg

Java kafka 6 月 优质更文活动

全方位整合生态能力,支付宝为小程序开发者升级一站式云服务

TRaaS

小程序 支付宝小程序 云服务 蚂蚁集团

六大类型JavaScript题型

不叫猫先生

JavaScript 6 月 优质更文活动

华为云CodeArtBuild减负!云端编译构建,让你的开发省时省力!

华为云PaaS服务小智

云计算 代码 华为云 编译构建

6 种方式读取 Springboot 的配置,老鸟都这么玩(原理+实战)

程序员小富

springboot

我为何停止使用Spring_语言 & 开发_张龙_InfoQ精选文章