合Spring时Service层为什么不做全局包扫描详解

一、Spring和SpringMVC的父子容器关系

1.讲问题之前要先明白一个关系

一般来说,我们在整合Spring和SpringMVC这两个框架中,web.xml会这样写到:

  <!-- 加载spring容器 -->
<!-- 初始化加载application.xml的各种配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/application-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- 配置springmvc前端控制器 -->
<servlet>
<servlet-name>taotao-manager</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- contextConfigLocation不是必须的, 如果不配置contextConfigLocation,
springmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

首先配置的是Spring容器的初始化加载的application文件,然后是SpringMVC的前端控制器(DispatchServlet),当配置完DispatchServlet后会在Spring容器中创建一个新的容器。其实这是两个容器,Spring作为父容器,SpringMVC作为子容器。

让我们用图来看一下这个父子关系的原理

平时我们在项目中注入关系是这样的顺序(结合图来说):在Service中注入Dao(初始化自动注入,利用@Autowired),接着在Controller里注入Service(初始化自动注入,利用@Autowired),看图,这就意味这作为SpringMVC的子容器是可以访问父容器Spring对象的。

那么问大家一个问题。要是反过来呢,你把Controller注入到Service中能行么? 
肯定是不行的啊!(如图,这也说明了父容器是不能调用子容器对象的)

如果Dao,Serive,Controller要是都在Spring容器中,无疑上边的问题是肯定的,因为都是在一个bean里,一个容器中。

2.问题:为什么不能在Spring中的Service层配置全局扫描?

例如:一个项目中我总项目的名字叫com.shop,我们在配置applicationContext-service.xml中,包扫描代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
...../ 此处省略> <!-- 扫描包Service实现类 -->
<context:component-scan base-package="com.shop.service"></context:component-scan>
</beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上面所配置的是一个局部扫描,而不是全局扫描。接下来说原因:

这里就和上面讲到的父子容器有关系,假设我们做了全局扫描那么代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
...../ 此处省略> <!-- 扫描包Service实现类 -->
<context:component-scan base-package="com.shop"></context:component-scan>
</beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

此时的Spring容器中就会扫描到@Controller,@Service,@Reposity,@Component,此时的图如下

结合图去看,相当于他们都会放到大的容器中,而这时的SpringMVC容器中没有对象,没有对象就没有Controller,所以加载处理器,适配器的时候就会找不到映射对象,映射关系,因此在页面上就会出现404的错误。

3.如果不用Spring容器,直接把所有层放入SpringMVC容器中可不可以?

当然可以,如果没有Spring容器,我们是可以把所有层放入SpringMVC的。单独使用这个容器是完全可以的,而且是轻量级的。

4.那么为什么我们在项目中还要联合用到Spring容器和SpringMVC容器?

答案是: Spring的扩展性,如果要是项目需要加入Struts等可以整合进来,便于扩展框架。如果要是为了快,为了方便开发,完全可以用SpringMVC框架。

5.结论

如果在项目中我们在Service层做全局包扫描,那么springmvc不能提供服务,因为springmvc子容器中没有controller对象。

整合Spring时Service层为什么不做全局包扫描详解的更多相关文章

  1. spring盒springMVC整合父子容器问题:整合Spring时Service层为什么不做全局包扫描详解

    整合Spring时Service层为什么不做全局包扫描详解 一.Spring和SpringMVC的父子容器关系 1.讲问题之前要先明白一个关系 一般来说,我们在整合Spring和SpringMVC这两 ...

  2. quartz整合spring框架service层对象注入为null解决方案

    Job实现类代码 package cn.itcast.quartz; import org.quartz.Job; import org.quartz.JobExecutionContext; imp ...

  3. 2017.3.31 spring mvc教程(二)核心流程及配置详解

    学习的博客:http://elf8848.iteye.com/blog/875830/ 我项目中所用的版本:4.2.0.博客的时间比较早,11年的,学习的是Spring3 MVC.不知道版本上有没有变 ...

  4. Spring的Service层与Dao层解析

    本文转载于网络,觉得写得很透彻. dao完成连接数据库修改删除添加等的实现细节,例如sql语句是怎么写的,怎么把对象放入数据库的.service层是面向功能的,一个个功能模块比如说银行登记并完成一次存 ...

  5. spring -mvc service层调用工具类配置

    在service层时调用工具类时服务返回工具类对象为空 在此工具类上加上@Component注解就可以了 @Component:把普通pojo实例化到spring容器中,相当于配置文件中的 <b ...

  6. spring在service层获取session和request

    首先要在web.xml增加如下代码: <listener> <listener-class>org.springframework.web.context.request.Re ...

  7. java普通类如何调用Spring的Service层?

    首先在Service层上面添加 @Service("myService") 然后,在main方法中调用,String[]中为配置文件,如下所示: ApplicationContex ...

  8. websocket 使用 spring 的service层 ,进而调用里面的 dao层 来操作数据库 ,包括redis、mysql等通用

    1.前言 描述一下今天用websocket踩得坑  --->空指针异常! 我想在websocket里面使用service 层的接口,从中获取数据库的一些信息  , 使用 @Autowired 注 ...

  9. Spring源码分析-从@ComponentScan注解配置包扫描路径到IoC容器中的BeanDefinition,经历了什么(一)?

    阅前提醒 全文较长,建议沉下心来慢慢阅读,最好是打开Idea,点开Spring源码,跟着下文一步一步阅读,更加便于理解.由于笔者水平优先,编写时间仓促,文中难免会出现一些错误或者不准确的地方,恳请各位 ...

随机推荐

  1. Linux下如何查看tomcat是否启动、查看tomcat启动日志(转)

    在Linux系统下,重启Tomcat使用命令的操作! 1.首先,进入Tomcat下的bin目录 cd /usr/local/tomcat/bin 使用Tomcat关闭命令 ./shutdown.sh ...

  2. Go文档:go命令

    目录 go go bug--启动bug报告 go build--编译包及其依赖包 go clean--删除对象文件和缓存文件 go doc--查看包或符号的文档 go env--打印环境变量 go f ...

  3. Aery的UE4 C++游戏开发之旅(4)加载资源&创建对象

    目录 资源的硬引用 硬指针 FObjectFinder<T> / FClassFinder<T> 资源的软引用 FSoftObjectPaths.FStringAssetRef ...

  4. DVWA靶机的命令执行漏洞

    之前在打攻防世界的时候出现过类似的题目,这里再重温一下 (靶机一共低中高三个安全等级,这里只演示低中等级) (1)Security:low 根据提示让我们输入地址ping一下,之后返回以下内容,可以判 ...

  5. 吴裕雄--天生自然PythonDjangoWeb企业开发:学员管理系统- 前台

    开发首页 做一个简单的用户提交申请的表单页面. 首先在student/views.py文件中编写下面的代码: # -*- coding: utf-8 -*- from __future__ impor ...

  6. 02-10Android学习进度报告十

    今天我学习了有关ListView的基础知识,主要是学习了其中界面展示的基本方法. 首先看一个简单的列表实现代码: public class Animal { private String aName; ...

  7. FineReport帆软报表需求:根据url传递过来的参数值决定显示隐藏列

    需求:角色id传递到报表页面中,然后根据角色id,决定隐藏第1列,显示第2-4列,还是隐藏第2-4列,显示第1列. 解决方法:

  8. 奈奎斯特采样定理(Nyquist)

    采样定理在1928年由美国电信工程师H.奈奎斯特首先提出来的,因此称为奈奎斯特采样定理. 1933年由苏联工程师科捷利尼科夫首次用公式严格地表述这一定理,因此在苏联文献中称为科捷利尼科夫采样定理. 1 ...

  9. jdbc学习over

    这次的代码和之前学习到一般的代码主要就是将一些很常见的操作(建立连接.清除连接)不管做什么操作都需要用到它们,所以将它们单独放到另一个工具类里面去. 用到的术语: 1.事务:https://www.c ...

  10. Codeforces1301C. Ayoub's function

    本题的收获是,要学会反向思维,正向找包含1的太多,我们就反向找,全排列-只有0的不满足题意的就是答案,一共有n-m个0,m个1,插空法,一共有m+1个地方可以插入0序列,总排列数为(n+1)*n/2, ...