使用Spring MVC时的常见错误

spring_framework 当我大约10年前开始我的职业生涯时,Struts MVC就是市场上的常态。 但是,多年来,我观察到Spring MVC逐渐流行起来。 鉴于Spring MVC与Spring容器的无缝集成以及它提供的灵活性和可扩展性,这对我来说并不奇怪。

从到目前为止的Spring旅程中,我通常会看到人们在配置Spring框架时犯了一些常见的错误。 与人们仍然使用Struts框架的时间相比,这种情况发生的频率更高。 我想这是灵活性和可用性之间的权衡。 另外,Spring文档中有很多示例,但缺乏解释。 为了填补这一空白,本文将尝试阐述和解释我经常看到的3个常见问题。

在Servlet上下文定义文件中声明bean

因此,我们每个人都知道Spring使用ContextLoaderListener加载Spring应用程序上下文。 不过,当宣布
DispatcherServlet ,我们需要创建名称为“ $ {servlet.name} -context.xml”的servlet上下文定义文件。 有没有想过为什么?

应用程序上下文层次结构

并非所有开发人员都知道Spring应用程序上下文具有层次结构。 让我们看一下这种方法:

org.springframework.context.ApplicationContext.getParent()

它告诉我们Spring Application Context具有父级。 那么,这个父母干什么呢?

如果下载源代码并进行快速引用搜索,则应该发现Spring Application Context将parent作为其扩展名。 如果您不介意阅读代码,请让我向您展示方法BeanFactoryUtils.beansOfTypeIn includedAncestors()中的用法示例:

if (lbf instanceof HierarchicalBeanFactory) {HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {Map parentResult = beansOfTypeIncludingAncestors((ListableBeanFactory) hbf.getParentBeanFactory(), type);...}
}
return result;
}

如果遍历整个方法,您将发现在搜索父上下文之前,Spring Application Context会扫描以在内部上下文中查找bean。 通过这种策略,Spring Application Context将有效地进行反向广度优先搜索以查找bean。

ContextLoaderListener

这是每个开发人员都应该知道的众所周知的类。 它有助于从预定义的上下文定义文件中加载Spring应用程序上下文。 由于实现了ServletContextListener ,因此将在加载Web应用程序后立即加载Spring应用程序上下文。 当加载包含带有@PostContruct批注或批处理作业的bean的Spring容器时,这带来了无可争议的好处。

相反,在初始化servlet之前,不会构造servlet上下文定义文件中的任何bean定义。 何时初始化Servlet? 这是不确定的。 在最坏的情况下,您可能需要等到用户对servlet映射URL进行第一次点击才能加载spring上下文。

根据以上信息,您应该在哪里声明所有珍贵的豆子? 我觉得这样做的最佳位置是ContextLoaderListener加载的上下文定义文件,而没有其他地方。 这里的窍门是将ApplicationContext作为servlet属性存储在键org.springframework.web.context.WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE下
稍后, DispatcherServlet将从ServletContext加载此上下文,并将其分配为父应用程序上下文。

protected WebApplicationContext initWebApplicationContext() {WebApplicationContext rootContext =WebApplicationContextUtils.getWebApplicationContext(getServletContext());...
}

由于这种行为,强烈建议创建一个空的servlet应用程序上下文定义文件,并在父上下文中定义您的bean。 这将有助于避免在加载Web应用程序时重复创建Bean,并确保立即执行批处理作业。

从理论上讲,在servlet应用程序上下文定义文件中定义bean会使该bean唯一且仅对该servlet可见。 但是,在使用Spring的8年中,除了定义Web Service端点之外,我几乎没有发现此功能的任何用途。

这是一个小错误,但是如果您不注意它,它将引起您的注意。 Log4jConfigListener是我在-Dlog4j.configuration首选的解决方案,我们可以控制的log4j加载不改变服务器的引导过程。

显然,这应该是在web.xml中声明的第一个侦听器。 否则,您浪费所有的时间来声明正确的日志记录配置。

由于对Bean的探索管理不善而复制了Bean

在Spring的早期,开发人员在xml文件上打字的时间比Java类花费的时间更多。 对于每个新bean,我们需要自己声明和连接依赖项,这是干净,整洁但非常痛苦的。 毫无疑问,Spring框架的更高版本向更高的可用性发展。 如今,开发人员可能只需要声明事务管理器,数据源,属性源,Web服务端点,其余的就可以进行组件扫描和自动装配。

我喜欢这些新功能,但是这种强大的力量需要承担巨大的责任。 否则,事情会很快变得混乱。 XML文件中的组件扫描和bean声明是完全独立的。 因此,如果对bean进行注释以进行组件扫描并手动进行声明,则在bean容器中完全可能具有相同类的相同bean。 幸运的是,这种错误应该只发生在初学者身上。

当我们需要将一些嵌入式组件集成到最终产品中时,情况变得更加复杂。 然后,我们确实需要一种策略来避免重复的bean声明。

spring_component

上图显示了我们日常生活中遇到的种种现实问题。 大多数情况下,系统是由多个组件组成的,通常,一个组件可为多个产品提供服务。 每个应用程序和组件都有自己的bean。 在这种情况下,最好的声明方式是避免重复的bean声明?

这是我建议的策略:

  • 确保每个组件都必须以专用的软件包名称开头。 当我们需要进行组件扫描时,它使我们的工作变得更轻松。
  • 不要指示开发组件的团队采用在组件本身中声明Bean的方法(注释与xml声明)。 开发人员负责将组件打包到最终产品中,以确保没有重复的bean声明。
  • 如果组件中包含上下文定义文件,请给它一个包,而不是放在classpath的根目录中。 最好给它起一个特定的名字。 例如, src / main / resources / spring-core / spring-core-context.xmlsrc / main / resource / application-context.xml更好 想象一下,如果在相同的程序包中打包几个包含相同文件application-context.xml的组件,那该怎么办!
  • 如果您已经在一个上下文文件中声明了Bean,则不要为组件扫描提供任何注释( @ Component, @ Service@Repository )。
  • 将特定于环境的bean(例如data-sourceproperty-source)拆分到一个单独的文件中并重用。
  • 不要在常规包装上进行组件扫描。 例如,与扫描org.springframework包相比,如果我们扫描几个子包(例如org.springframework.coreorg.springframework.contextorg.springframework.ui ,…), 则更易于管理。

结论

希望以上技巧对日常使用很有帮助。 如有任何疑问或任何其他想法,请发送反馈以提供帮助。

翻译自: https://www.javacodegeeks.com/2014/07/common-mistakes-when-using-spring-mvc.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363039.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ operator操作符重载(++,--,-,+,())

C中,--操作符重载需要说明是(--)在操作数前面,还是在操作数后面,区别如下: 代码经过测试无误(起码我这里没问题^_^)Code1#include <iostream> 2#include <cstdlib> 3using namespace std; 4template<typename T> class A 5{ 6public: 7 A(): m_(0){ 8 …

javax.el.PropertyNotFoundException: Property [Xxxx] not found on type Xxx.xxx.xxxx.Xxxx]的解决办法...

当我将后台数据传递给jsp&#xff0c;用${requestScope.user.Id}取值时报错&#xff0c; 最后发现entity实体类的属性不能首字母大写然后再小写&#xff0c;例如 int Age&#xff1b;这个就不行&#xff0c;必须写成int age; 最后问题解决了 转载于:https://www.cnblogs.com/Th…

初识C语言(五)

自定义函数 C语言提供了大量的库函数&#xff08;右侧资料下载中有&#xff09;&#xff0c;比如stdio.h提供输出函数&#xff0c;但是还是满足不了我们开发中的一些逻辑&#xff0c;所以这个时候需要自己定义函数&#xff0c;自定义函数的一般形式&#xff1a; 注意&#xff1…

nodeJS实现简单网页爬虫功能

前面的话 本文将使用nodeJS实现一个简单的网页爬虫功能 网页源码 使用http.get()方法获取网页源码&#xff0c;以hao123网站的头条页面为例 http://tuijian.hao123.com/hotrank var http require(http);http.get(http://tuijian.hao123.com/hotrank,function(res){var data ;…

JavaFX技巧6:使用透明颜色

为用户界面元素选择正确的颜色始终是一个很大的挑战&#xff0c;但是当您开发可重用的框架控件时&#xff0c;开发人员就无法控制使用它们的应用程序的外观和感觉&#xff0c;这甚至更具挑战性。 尽管您可能总是将元素添加到默认的灰色背景之上&#xff0c;但是嵌入控件的开发人…

38.QT-QAxObject快速写入EXCEL示例

参考链接: https://blog.csdn.net/czyt1988/article/details/52121360 http://blog.sina.com.cn/s/blog_a6fb6cc90101gv2p.html 1. QAxObject介绍 在QT中,有个自带的QAxObject类,可以直接操作EXCEL 除此之外,当我们操作某个文件夹下的EXCEL的时候,都会在该文件夹下出现一个隐藏…

EA常见画图(类图、包图、构件图、状态图、顺序图、活动图)

EA常见活动图&#xff0c;状态图画法 类图:111&#xff08;1&#xff09;给关系添加注释&#xff08;2&#xff09;设置关系线样式 包图&#xff1a;&#xff08;1&#xff09;创建包图&#xff08;2&#xff09;在包中添加子包&#xff1a;&#xff08;3&#xff09;在包中添加…

我最喜欢的IntelliJ IDEA功能

我已经是IntelliJ IDEA的长期用户&#xff08;和客户&#xff09;。 我想我是在2005年或2006年&#xff08;版本5.0&#xff09;左右开始使用它的。 那时我是Eclipse用户。 我的一些同事向我推荐了它&#xff0c;起初我没有被说服&#xff0c;但是在尝试之后我印象深刻。 现在…

selenium 常见问题

启动selenium时报错如下异常&#xff1a; selenium.common.exceptions.WebDriverException: Message: geckodriver executable needs to be in PATH. 解决方式&#xff1a;需要下载geckodriver&#xff0c;并放在path的环境变量下&#xff0c;下载地址&#xff1a;https://gith…

通过示例了解挥发

我们已经花了几个月的时间来稳定Plumbr中的锁定检测功能 。 在此期间&#xff0c;我们遇到了许多棘手的并发问题。 许多问题是独特的&#xff0c;但是一种特殊类型的问题一直反复出现。 您可能已经猜到了–滥用volatile关键字。 我们已经发现并解决了许多问题&#xff0c;其中…

HDU 1212 Big Number

题意&#xff1a;给一数字字符串s ( ns.size()<1000 ) 和数字m (<1e5) 求s%m 模拟除法&#xff0c; k初值0&#xff0c;按s[0]...累乘相加&#xff0c;把字符串还原成数字&#xff0c;比m大时-m&#xff0c;继续按位还原到s[n-1] 此时剩下的k再%m即为所求 #include<…

BOM之navigator对象和用户代理检测

前面的话 navigator对象现在已经成为识别客户端浏览器的事实标准&#xff0c;navigator对象是所有支持javascript的浏览器所共有的。本文将详细介绍navigator对象和用户代理检测 属性 与其他BOM对象的情况一样&#xff0c;每个浏览器中的navigator对象也都有一套自己的属性。下…

智能自动PPR更改事件策略

ADF开发人员普遍认为&#xff0c;将迭代器绑定更改事件策略设置为ppr在性能方面不是一件好事&#xff0c;因为此策略会强制框架刷新每个请求上绑定到此迭代器的所有属性绑定。 这不是真的&#xff01; 框架仅刷新在请求期间已更改的属性和依赖于已更改属性的属性。 让我们考虑…

装饰器设计模式的应用

嗨&#xff0c;您好&#xff01; 今天&#xff0c;我将展示装饰设计模式的实际应用。 装饰器设计模式是一种广泛使用的设计模式&#xff0c;同时在运行期间处理图形&#xff0c;树木和动态更改。 如果您正在寻找或尝试进行递归&#xff0c;这也是一个不错的选择。 我喜欢它。…

构造函数 基本使用

相关知识点&#xff1a; 构造函数、原型对象、实例对象 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta h…

Vista,Windows7中给IIS7添加PHP支持

截止到发文时&#xff08;2009年9月25日&#xff09;&#xff0c;PHP是最新版本为5.3.0&#xff0c;但是5.3.0在IIS中的运行方式是FastCGI&#xff0c;要在Vista的IIS7上实现这一点我始终没弄成。最后我还是用的老方法&#xff0c;ISAPI&#xff0c;选用了一个5.3以前的版本&am…

python画手绘图

第一步&#xff1a;插入代码 #e17.1HandDrawPic.py from PIL import Image import numpy as np vec_el np.pi/2.2 # 光源的俯视角度&#xff0c;弧度值 vec_az np.pi/4. # 光源的方位角度&#xff0c;弧度值 depth 10. # (0-100) im Image.open(C:\\Users\\Thinkpad\\Deskt…

解读阿里巴巴集团的“大中台、小前台”组织战略

解读阿里巴巴集团的“大中台、小前台”组织战略 https://www.iyiou.com/p/92012.html 亿欧导读 ] 阿里的“中台战略” 不是一个简单的组织变革&#xff0c;还有业务变革、机制变革、技术架构变革的一次全面转型。 【编者按】阿里巴巴“大中台小前台”的中台战略的官方提法源自2…

深入理解DOM节点关系

前面的话 DOM可以将任何HTML描绘成一个由多层节点构成的结构。节点分为12种不同类型&#xff0c;每种类型分别表示文档中不同的信息及标记。每个节点都拥有各自的特点、数据和方法&#xff0c;也与其他节点存在某种关系。节点之间的关系构成了层次&#xff0c;而所有页面标记则…

分布式锁(基于redis和zookeeper)详解

分布式锁&#xff08;基于redis和zookeeper&#xff09;详解 https://blog.csdn.net/a15835774652/article/details/81775044 为什么写这篇文章&#xff1f; 目前网上大部分的基于zookeeper&#xff0c;和redis的分布式锁的文章都不够全面。要么就是特意避开集群的情况&#xf…