BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

我为何停止使用Spring

| 作者 张龙 关注 14 他的粉丝 发布于 2013年12月27日. 估计阅读时间: 8 分钟 | ArchSummit北京2018 共同探讨机器学习、信息安全、微服务治理的关键点

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框架的性价比高么?欢迎发表评论与大家一同分享你的观点与看法。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

张老师做翻译了吧.. by 曾 国泰

张老师做翻译了吧..

spring更好一点 by tang kai

如果说还有比spring更好的框架当然愿意使用了,我们在开发当中更多的是快速而清晰的去开发项目,使用spring我们可以清楚的看到三层结构,对项目有一个很清楚的认识,如果其他的框架也可以做到,并且开发的复杂度也比spring要简单那么请推荐一个,愿意学习了解

Re: 张老师做翻译了吧.. by 龙 张

业余时间翻译的

为什么不用OSGi或者OSGi.NET呢? by Chen Zhen-bao

我也不喜欢IoC,一方面IoC太碎片化,另一方面,使用IoC后,代码变得不直接,不简单了。很多时候,一些业务功能压根就不需要解耦,不依赖于IoC的话,我们可以轻而易举的编码、调试和维护。IoC太繁琐了。

在开发大型应用系统时,使其简单的方式我觉得是“化整为零”,通过“模块化 + 分层”来简单构建系统,模块内部可以是紧耦合的,模块间可以是松耦合的。这正是OSGi或者OSGi.NET的优势。

使用OSGi来开发Java的系统还比较复杂,不过使用OSGi.NET则非常简单。反正我喜欢的就是模块化、简单直接的开发方式,这种方式让团队协作开发更加简答。

Re: spring更好一点 by bing liu

spring是好的,但很多人(包括所谓的资深开发者)很多时候都是为了用spring而spring。其效果和直接new没有区别,反而要维护一套spring的配置,还不如new来的直接。放不放弃spring还是因人因事而异

spring开发模块化 by 王 笨笨我

现在好多人用spring,都是因为大家都在用,真正理解spring的可能没有几个人。spring还是有很多好处的,但是他不能热重启,在完全面向模块化开发的时候好像有点力不从心。比如在一个流程中加入一个模块来增加新的处理逻辑,就需要重启整个app,以使spring的容器能识别那个新的模块。不知道大家有没有什么好的办法

Re: spring开发模块化 by 杨 浩

可以自己实现的。这个并不难

原文链接 by yang samuel

可以提供原文链接么?谢谢

英文链接 by yang samuel

可以提供英文链接么?

是否可以选择Guice? by robin zhang

仅仅为了DI AOP为什么不选择Guice?没有烦人的xml,标准inject标签的支持,迁移兼容不错。

Spring还是很不错的 by 李 鹏

现在正在开发的项目,依旧选择了Spring框架,对于事务的管理,以及依赖注入和AOP的思想,确实可以让系统中本来很繁琐的地方变得清晰和优美。

Spring还是很不错的 by 李 鹏

现在正在开发的项目,依旧选择了Spring框架,对于事务的管理,以及依赖注入和AOP的思想,确实可以让系统中本来很繁琐的地方变得清晰和优美。

Spring还是很不错的 by 李 鹏

现在正在开发的项目,依旧选择了Spring框架,对于事务的管理,以及依赖注入和AOP的思想,确实可以让系统中本来很繁琐的地方变得清晰和优美。

Spring还是很不错的 by 李 鹏

现在正在开发的项目,依旧选择了Spring框架,对于事务的管理,以及依赖注入和AOP的思想,确实可以让系统中本来很繁琐的地方变得清晰和优美。

Spring还是很不错的 by 李 鹏

现在正在开发的项目,依旧选择了Spring框架,对于事务的管理,以及依赖注入和AOP的思想,确实可以让系统中本来很繁琐的地方变得清晰和优美。

Spring还是很不错的 by 李 鹏

现在正在开发的项目,依旧选择了Spring框架,对于事务的管理,以及依赖注入和AOP的思想,确实可以让系统中本来很繁琐的地方变得清晰和优美。

Spring还是很不错的 by 李 鹏

现在正在开发的项目,依旧选择了Spring框架,对于事务的管理,以及依赖注入和AOP的思想,确实可以让系统中本来很繁琐的地方变得清晰和优美。

Re: Spring还是很不错的 by Wang James

SPRING是帮助开发者来比较容易地实现自己的架构设计,开发者及团队不能因为有了工具而滥用工具。但事实上工具被滥用是很常见的事情,需要团队技术负责人注意。

整个Web应用需要的东西 by Wong Peter

一个依赖注入管理系统、一个持久化框架、一个安全框架与一个AOP系统(管理事务、安全等东西)。

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

19 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT