Spring和SpringMVC父子的容器之道---[上篇]
昨天,给数据组写接口,不小心掉进坑里挣扎了半天,最后发现是spring和springmvc它们虽是父子但并不和谐,于是在此一记。
Spring和SpringMVC作为Bean管理容器和MVC层的默认框架,已被众多WEB应用采用,而在实际开发中,由于有了强大的注解功能,很多基于XML的配置方式已经被替代,但在实际项目中,我们经常会同时配置Spring和SpringMVC的配置文件,分层来管理它们,但是有时候就会出现那么一些奇怪的异常,一旦进坑,让你无法自拔,就在昨天给数据组写接口时,我进坑了,就在坑里浑浑噩噩得度分如年,虽然当时很难受很浮躁,但是此刻在总写这篇博文时我心里是很高兴的,真的各位。
首先,我得帮助大家理解一下父子容器(2个容器)以及它们是如何初始化的,还有就是它们父子如何共享bean资源的。打个比方:老子的资产儿子可以使用,但是儿子的财产老子一般是不使用的;反过来说,Spring父容器中对于SpringMVC子容器中的bean是不可见的,反之,子容器中对于父容器中的bean是可见的。意思就是这个意思,这些概念我也是这俩天才脑补的,以前也没个正形,各位将就读读吧,文章末尾是我专门去给各位扒的美图,请各位慢用(是关于父子容器中bean的可见性和web容器如何初始化它们的)。
到这儿,我废话不多说了,直接给大家把我昨天进坑和出坑的场景简单描述一下。
场景一:由父子容器参与的项目中开启定时任务,由于包扫描的范围大小,儿子的定时任务失效了?各位他们虽为父子,但是也不和谐啊,你以为是相亲相爱一家人资源共享啊,我滴孩啊不是的。在springmvc的核心配置文件中扫描了com.zxz.action包结构,在spring的管理配置文件中首先开启了扫描定时任务的注解配置<task:annotation-driven />,然后扫描了com.zxz.service包结构,但是没有触及到子容器的地盘,这下坏了这蒙在鼓里的我菜鸟,同时开启俩个世界的定时任务,还在傻傻的打开控制台等着执行呢,但是只有爹的定时任务如愿以偿,但是儿子的定时任务挂了,.........经过一段时间的纠结,发现了问题,因为它们是2个容器,2个容器啊,不是你在这个容器里配置了,就代表那个容器也会生效啊,不会的,你得分清,爹的是爹的,儿子的是儿子的。
项目包结构如下:
service层的定时任务:
1 /**
2 * 开启Spring容器扫描包范围内的定时任务
3 */
4 @Scheduled(cron = "0/3 * * * * ? ")
5 public void serviceTask(){
6 System.out.println("Service**********");
7 }
controller层的定时任务:
1 /**
2 * 开启SpringMVC容器扫描包范围内的定时任务
3 */
4 @Scheduled(cron = "0/6 * * * * ? ")
5 public void webTask(){
6 System.out.println("Controller**********");
7 }
儿子的定时任务没有执行的配置:
1 <!-- task任务扫描注解 -->
2 <task:annotation-driven />
3
4 <!-- 开启Spring容器的包扫描 -->
5 <context:component-scan base-package="com.zxz.service"/>
扩大定时任务扫描的包结构的配置:
1 <!-- task任务扫描注解 -->
2 <task:annotation-driven />
3
4 <!-- 开启Spring容器的包扫描 -->
5 <context:component-scan base-package="com.zxz"/>
场景二:由父子容器参与的项目中加载配置文件中的常量值,由于疏忽导致在父容器的配置文件中没有配置加载资源文件的那项配置,在service层的代码中始终没有获取到相关常量的值?上面说了,2个容器各自使用各自的。我们在开发中经常有这么一个动作,就是将项目中不变的常量和它们的值都习惯存储到某个资源文件中,如果在代码中需要使用它们的值则可以直接获取,不用再去代码中查找到对应的常量并修改他们的值,那是愚蠢的做法,极其不方便,聪明人都是会提取出来的为了修改方便维护方便。我这个项目里所有的常量和它们值都放在resource.propertie资源文件里了,但是由于我的忽视,我高看了spring他们一家人的关系,导致我service层的代码一直报NullPointerException异常,让我断点调试卡了半天.......哎,最后发现我没有在父容器的配置文件中没有配置加载项,我彻底恍惚了,不知道自己是大意还是菜,总之这些就是一些非常细微的细节,各位。
controller层和service层同时加载常量(如果使用spring和springmvc来作为容器,则记得同时配置哦):
父子容器中加载资源文件的配置:
1 <!-- 加载java资源文件 -->
2 <context:property-placeholder location="classpath*:properties/*.propertie"/>
好了各位,我分享的东西暂时就这么多,因为我有把握的就这么多,但是我从网上看到父子容器导致的问题还很多,比如可以让事务失效啊什么的,菜鸟在进一步探索,如果有结果会给各位准时报告的。如果博文中有什么不对的地方,请留言,我会及时查证并修改的,谢谢各位的捧场(还有别忘了看图)。
图一:父子容器中bean的可见性。
图二:父子容器的初始化情况。
- 微信快速开发框架(八)-- V2.3--增加语音识别及网页获取用户信息,代码已更新至Github
- 微信公众平台快速开发框架 For Core 2.0 beta –JCSoft.WX.Core 5.2.0 beta发布
- Android系统层Watchdog机制源码分析
- 算法之插入排序
- Android Studio环境下搭建ReactNative
- Android实现两个ScrollView互相联动,同步滚动的效果
- 一个可以拖动的自定义Gridview代码
- android图片加载库Glide
- 密码最短长度为7,其中必须包含以下非字母数字字符1 完美解决方案
- android开发性能分析
- url带中文参数显示乱码的问题
- 转换程序的一些问题:设置为 OFF 时,不能为表 'Test' 中的标识列插入显式值。8cad0260
- JQuery 对控件的事件操作
- 流畅地HtmlHelper-Asp.Net MVC
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- Android之ImageSwitcher的实例详解
- Android中HTTP请求中文乱码解决办法
- Android编程之播放器MediaPlayer实现均衡器效果示例
- Android studio点击跳转WebView详解
- Android webveiw 出现栈错误解决办法
- Android开发之实现手势滑动的功能
- Android编程实现带有单选按钮和复选按钮的dialog功能示例
- Android中Retrofit 2.0直接使用JSON进行数据交互
- Android自定义Drawable实现圆形和圆角
- Android jni调试打印char阵列的实例详解
- 写JavaScript函数不得不知的高级技巧
- Android编程视频播放API之MediaPlayer用法示例
- Android实现点击缩略图放大效果
- Android 应用签名的两种方法
- Android 关闭多个Activity的实现方法