spring框架解决了什么问题,spring框架异常处理
00-1010春天的缺点是无法理解的。为什么是Spring IoC根据评论排查编程问题?选择别人说的话,前言:.
曾几何时,Spring framework提供了比J2EE更轻便、更灵活的解决方案。即使在2013年左右,我也很高兴能在那个时候了解到更多关于新春天4的信息。现在,七年过去了,当我看到春天的时候,我感到一阵恐慌。Comments和@ComponentScan已经用更好的东西取代了XML,这需要一个可视化工具来理解您的系统。春天已经变成了一条不断生长(和变化)的九头蛇。我接手,试图理解别人写的Spring应用,让我苦不堪言。但最后但同样重要的是,Clojure教会了我代码可以/应该有多简单。那么,我对春天的主要问题是什么?
(需要明确的是,我说的Spring,主要是指Spring Control Inversion (IoC)及其依赖注入子集。)
目录
Spring的缺点
系统构成的黑箱:
和组件扫描对于快速启动和运行应用程序非常有用。但当你试图理解这些应用程序时,它们简直是一场噩梦。由于@Configurations和@bean来自您的代码库、公司库的任何地方,并且可能来自100MB的Spring依赖项(真实情况),所以不可能清楚地了解应用程序的结构和配置。基本上,你需要一次又一次地为Spring和所有库进行RTFM,以便记住所有可能需要的东西,并通读整个代码库。IntelliJ SpringBeans view之类的工具可能会有所帮助(如果你能正常工作的话)。
在这里,我完全赞同Python的禅宗“明的比隐的好”
在一个典型的Clojure项目中,我进入了core/main名称空间,在那里main函数启动服务器并为它提供处理功能,可能(手动地)使用一些中间件包装器,也可能在内部使用库进行路由。我可能还会读取配置并传递它。我可以轻松地点击浏览代码,查看代码中的具体部分以及它们是如何协同工作的。即使在cljdoc这样的大型系统中。Org有一个主功能启动服务器(这里是Integrant),并为其提供配置和“系统定义”(类似Springbean Tree)。一切都很清楚,可以导航。
00-1010能够将元数据添加到方法和类中是很棒的。我并不反对@ get mapping(“/”)这样的东西。但它通常用于绕过Java的限制,通过@Scheduled和@Transactional等注释实现横切关注点。我曾经是AOP的坚定支持者。由于语言的限制,AOP仍然是Java开发者不可或缺的工具,但我也意识到它的成本不容忽视。问题是你不容易看到它在做什么(因为它除了数据什么都不做)。为了给你一个视角,替换@ Transactional Person find Person db(String Personid){.}在Clojure中,我只需要用一个自定义宏来包装它,比如:
(defn find-person-in-db[person-id](事务性.))实质性的区别在于,我可以控制点击来导航到宏,并查看它在做什么,所以所有的行为都在那里供我检查和理解。祝你在春天找到答案!
不可理解性
春天是让很多事情快速启动的好时机3354直到某件事情失败或者不按预期工作。Spring是一个松散耦合的意大利面球。在我痛苦的经历中,很难解决。文档很多,但经常找不到需要的答案。可能官方文件太肤浅了,有时候依赖很多已有的知识。搜索有时提供一个解决方案,有时至少是有用的指针,有时是误导性/陈旧的信息,有时什么都没有。排除故障时,你需要在这个庞大而复杂的类中挣扎。这些类以某种方式协同工作(或者应该协同工作),并且以一种(看似)神秘的方式受类路径上的jar和@配置的影响。希望你能偶然发现问题的原因。
例如,我花了相当长的时间来理解Spring MVC应用程序中的错误处理是如何工作的。我们有一个由@ controller advice([ myapp . endpoint . API ])myapp . endpoint . API . advice . ErrorHandler调用的error handler(如果你记得抛出正确的异常类型),@ component myapp . spring . errorpagescustomi。
zer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>将container.addErrorPages(new ErrorPage("/error"))错误发送到org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController,然后它将神奇地呈现我们的错误。类路径上的html。我意识到我再也不明白(如果我真的明白的话)它到底是如何工作的了。但要以所需的方式显示错误,无疑是一场斗争。
另一个难点是理解为什么Spring返回404而不是预期的文件。我对它的请求处理有很多来之不易的知识,也许有一天会成为一篇博客文章。
了解@Scheduled jobs
实际上是如何调度的,并试图找出为什么一个作业没有按预期运行,以及增加线程池大小以使其不再被较慢的作业停止的神奇调用是什么,这需要几天的时间和多次失败的尝试,我甚至放弃了一次或两次。搜索互联网提供了一些帮助,但肯定远远不够。这是我的一般经验,与Spring有关。
在Spring升级后搜索突然出现的ClassNotFound
运行时错误,试图找出哪个Spring JAR有这个类,哪个版本是正确的,或者如何更改配置以停止需要更改… 不,谢谢你。
为什么是Spring IoC?
这是一个由两部分组成的问题:为什么是Spring IoC?为什么是Spring?
许多开发人员都知道,Spring是一个成熟且流行的解决方案。它还为几乎所有问题提供了解决方案,这些解决方案通常能够很好地协同工作。您也可以快速开始。另一方面,你可能会争辩说,这是夸大其词,有遗留问题,而且——通过尝试为每个人做每件事——没有做得完美,更小、专注的解决方案可能更好(尽管你需要整合它们)。
为什么选择依赖注入和IoC?您可以从中找到许多原因:使用依赖注入和IoC容器的好处是什么?。
其中一些是:
简化-您的类不需要知道如何创建它们的依赖项(以及它们需要什么)。您可以将实例化和连接类的问题分离出来。灵活性—您现在可以提供不同的/修饰的实现。因此,在测试中,您可以提供模拟实现,在大型复杂系统中,通过交换新的实现(这部分取决于对接口的编程),您可以使用疑难解答装饰器包装依赖项,从而使其更容易逐步重构。生命周期控制查看维基百科上列出的优点和缺点。但它有明显的好处,这并不意味着你应该在任何地方、任何事情上都使用它。记住成本和劣势,做出有根据的决策。
我们通常在Clojure-f.ex中使用依赖注入。接下来是数据库访问库。jdbc要求您将目标数据源传递给每个调用。(这使您可以自由地创建自己的包装器来控制数据源并将其传递给库(如果您愿意的话)在Cognitect AWS API中构造AWS客户端时,可以让它创建默认的底层HTTP客户端,也可以提供自己的客户端,这样就可以覆盖默认的依赖关系。我们甚至有一些人喜欢使用的依赖注入框架,如组件和上下文,而其他经验丰富的开发人员则觉得它们不必要。
选择
当谈到Spring生态系统作为一个整体时,您应该始终应用Alex的合理库原则:不要添加库,直到没有库的痛苦如此之大,您无法忍受没有它的生活(并且在适当探索了其他选择之后)。
当您需要依赖注入时,最好手动组合系统。当前的小型微服务时代与诞生Spring的巨型应用时代截然不同。你可以自己做(为什么不?!)或者使用一种重量轻、重点突出的解决方案来解决更为手动的问题,例如Feather。尽可能喜欢编程配置。Feather仍然是由CDI的@Provides
驱动的注释,但至少您在一个module类中声明了这些注释,您显式地向Feather注册了这些注释,并显式地向Feather请求所需的实例。在过去,我们使用Guice和手动调用来绑定每个微服务的主类。对于我这个当时经验丰富的Spring用户来说,这似乎很奇怪,也很错误,但我开始理解并欣赏它。甚至还有用于Spring Boot的(实验性)编程配置DSL JaFu(Kotlin,KoFu也有一个)。
据一些人说,Jakarta(Java EE的后代)是Spring生态系统的一个更干净、更小、更好的替代品。您还可以针对特定需求搜索单个解决方案。
我从一位受人尊敬的同事那里听到了Micronaut的好消息,它提供了低开销的DI和AOP、REST客户端/服务器、反应式、断路器等,但它仍然依赖(似乎)类路径扫描进行配置,因此保留了我在Spring中的主要问题。还有反应型Helidon SE,它具有透明的的开发经验;纯java应用程序开发,无注释,无依赖注入与这两个领域相同的领域是Quarkus,但其IoC基于CDI,因此与Spring有相同的问题。EclipseVert.X 专注于反应式、事件驱动的应用程序有所不同,但提供了类似的功能(HTTP客户端/服务器、OpenAPI、GraphQL、DB访问、配置、断路器、安全性、度量),并具有编程配置;相反,它不提供依赖注入(但您可能不需要它(尽管总线本身也有问题))。
其他人在说什么
在为本文做研究时,我发现了一些值得分享的经验和观点。
著名的挪威软件架构师Johannes Brodwall写道(2013年,再次遥遥领先于我):
我发现DI容器给我的一些直觉让我改进了设计,但同时,我发现当我移除容器时,解决方案变小了(这很好!),更易于导航和理解,更易于测试。我发现使用容器的成本非常高,这会导致复杂性和大小的增加,以及一致性的降低。
在这场Quora讨论中,有很多好的建议:为什么大多数母语不是Java的程序员似乎对Spring框架持反对意见,他们对Spring框架的哲学有什么不喜欢的?
这方面的问题是:Spring有点破坏了我们从使用Java中获得的简单性好处。Spring谨慎地将复杂性引入到您的项目中,当它工作时,框架表面上很简单,但老实说,有多少人可以解释Spring中发生的事情?调试Spring错误通常看起来像是魔术,需要90%的猜测和模式匹配。Spring通常可以在项目开始时为您节省数周的工作时间,您可能会觉得这些好处是免费的,但事实并非如此。在某些方面,您可以将其与在项目中使用动态编程语言的早期好处进行类比。在项目的初始阶段,它会大大加快您的速度,但复杂性和技术债务会在稍后的阶段打击您。
(当然,他与动态编程语言的比较与我和其他人使用Clojure的经验相反。)
所以他们改成了基于注释的配置,被迫学习,但我还是不喜欢。它仍然不是真正的Java。许多事情都是靠魔法发生的——当它们没有发生时,它们都以同样的方式失败,什么都没有发生。因此,您编辑并重新编译,同样不会发生任何事情。无法判断您是否注释了错误的内容,或者您的注释所说的内容是否与您认为的不同,或者您是否构建了错误的测试。
如果有像样的文档,我还没有看到。我最近研究了RequestParam,它是Spring MVC中普遍存在的一部分,以了解其语义。该页面实际上是无用的。Javadoc是API通信的主要方式;即使有更好的文档存在,这个页面也不会告诉我太多。
关于现代Java应用程序:
Main方法有一行起始Spring和许多类,每个类有5个注释。它们是如何被实例化的,以什么顺序,如果出现问题,如何调试这个过程
下面是我最讨厌Spring的几件事:
它确实会减慢应用程序的启动时间,在运行应用程序之前,你不会知道你的应用程序是否正常工作——在大型商业环境中,这意味着最多需要一个小时的构建和部署时间…然后会得到大量的stacktrace,其中一半与内部spring类有关,一旦您超越了简单的单例布线场景,Spring就会变得非常丑陋、非常脆弱和不可预测,这有助于您起步,但您走得越远,维护的噩梦就越大。
结论
那么,Spring是邪恶的,应该不惜任何代价避免吗?不需要。它使人们能够克服Java的局限性,并提供了许多库来解决实际问题。但它也是巨大、复杂的,而且维护成本很高。对引入库持怀疑态度,考虑多种解决方案,并为您的案例选择最佳解决方案,而不仅仅是Spring解决方案。即使在使用DI和IoC(Spring或其他)时,也要努力实现最大的透明度,并且更喜欢编程配置而不是类路径扫描。如果其他一切都失败了,请编写良好的(java)文档,以便您的继任者能够理解您的系统。
到此这篇关于深入介绍Spring框架及故障排除的文章就介绍到这了,更多相关 Spring框架 内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。