素材巴巴 > 程序开发 >

Spring4MVC(四)整合Spring

程序开发 2023-09-11 22:37:00

1、是否需要进行Spring和SpringMVC的整合?

       其实SpringMVC是Spring的一部分,它已经是运行在Spring容器中的,既然如此,还有必要进行Spring和SpringMVC的整合吗在实际开发中,基本上都是会进行整合的,至少我还没看到过没有进行整合的。那么整合操作是必须的吗?答案是否定的。

1.1 需要整合

       一般都是会进行两者的整合,因为,类似于数据源,事务,整合其他框架(比如MyBatis)都是放在 Spring 的配置文件中(而不是放在 SpringMVC 的配置文件中)。实际上放入 Spring 配置文件对应的 IOC 容器中的还有 Service 和 Dao。所以不应该把这么的事情都交给SpringMVC来完成。

1.2 不需要整合

       其实也可以把所有的配置信息,都放在 SpringMVC 的配置文件中;也可以分多个 Spring 的配置文件,然后使用 import 节点导入其他的配置文件(或者在web.xml中配置DispatchServlet的时候,使用通配符指定配置文件的名称)。

      但是,这种方式不推荐,这也不是Spring的初衷。

2、Spring整合SpringMVC

创建一个新的工程SpringMVC_Spring,演示Spring和SpringMVC的整合;

2.1 创建web工程SpringMVC_Spring

创建工程(IDEA创建web工程的方式可以参考第一篇SpringMVC的文章),导入jar包:

jar包不需要这么全,只要有最重要的几个包就可以了,这里是展示了所有的包

2.2 配置Spring的监听器和SpringMVC的servlet

在web.xml中配置Spring的监听器和SpringMVC的servlet:


 org.springframework.web.context.ContextLoaderListenercontextConfigLocationclasspath:spring/applicationContext*.xmldispatcherServletorg.springframework.web.servlet.DispatcherServletcontextConfigLocationclasspath:spring/springmvc*.xml1dispatcherServlet/

web.xml中,使用了通配符的方式来指定配置文件的名称以及位置:

classpath*:spring/applicationContext*.xmlclasspath*:spring/springmvc*.xml

这样就会去classpath下面去找spring目录下的以applicationContext开头和以springmvc开头的配置文件。

2.3 创建Spring和SpringMVC的配置文件

2.3.1 创建Spring的配置文件

       在项目的classpath下面创建目录spring,然后在该目录下创建applicationContext-mvc.xml(因为我们使用了通配符,所以这个命名也是可以的):


 

2.3.2 创建SpringMVC的配置文件

        在项目的目录spring下创建springmvc-spring.xml(因为我们使用了通配符,所以这个命名也是可以的):


 

3、处理器和业务层编写

3.1 创建业务层Service

在src下面新建包com.springmvc(配置文件中扫描的包路径),下面新建一个TestService

package com.springmvc;import org.springframework.stereotype.Service;@Service
 public class TestService {//这个构造方法只是为了显示该类被创建了几次public TestService(){System.out.println("TestService创建了。。。");}public String getName(){return "Spring";}
 }
 

3.2 创建处理器Controller

在包com.springmvc(配置文件中扫描的包路径),下面新建一个TestController

package com.springmvc;import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.servlet.ModelAndView;@Controller
 @RequestMapping("springmvc")
 public class TestController {//这个构造方法只是为了显示该类被创建了几次public TestController() {System.out.println("TestController被创建了。。。");}@Autowiredprivate TestService testService;@RequestMapping("testSpring")public ModelAndView testSpring(){String name = testService.getName();ModelAndView modelAndView = new ModelAndView("success");modelAndView.addObject("name",name);return modelAndView;}
 }
 

4、前台页面编写

4.1 首页添加超链接

点击获取名称

4.2 创建一个成功页面success.jsp

       因为我们的TestController中,请求处理成功,在ModelAndView中设置了名称为success的视图,所以需要在WEB-INF的views目录下面创建success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
 成功页面

SUCCESS PAGE

Hello ${name}

5、存在的问题分析

存在的问题:同一个Bean被初始化了两次。

5.1 演示上面的效果

启动项目,在首页点击超链接,页面跳转到success.jsp页面,效果如下:

咋一看,我们发现整合是成功的啊,但是我们查看控制台的打印如下:

       这是什么情况,这是在项目启动的时候,我们的处理器和业务类都被初始化了两次啊。因为Spring和SpringMVC都有自己的容器,而且需要注意的是,我们的TestController和TestService都是放在包com.springmvc下面的,并且我们在Spring和SpringMVC的配置文件中,配置的扫描包的路径也都是:com.springmvc

这样就导致:初始化Spring的IOC容器的时候和初始化SpringMVC的IOC容器时,都把这两个类给初始化了。

5.2 解决Bean重复初始化

5.2.1 不要重复扫描

       因为之前我们的Handler和Service都是放在同一个包下,这样配置包扫描的时候,就会把该包下面所有的都扫描了。因此我们可以把TestController放到com.springmvc.controller包下,把TestService放到com.springmvc.service包下,配置文件中的包扫描也是各自扫描给自的包:


 

5.2.2 配置包扫描的时候排除掉某些注解不扫描

       5.2.1 的方法虽然也可以解决问题,但是这样也有不便的地方。因为在分模块开发的时候,每个模块下面都有Controller和Service,这样的话,就导致扫描路径不是很好去区分的。

       我们可以在标签里面使用两个子标签:来进行更细化的配置,可以指定扫描的注解和不扫描的注解。

       在SpringMVC的配置文件中,可以使用来指定 只扫描注解:@Controller和@ControllerAdvice

use-default-filters="false" 这个别忘记改成false,就是不使用默认的扫描规则,默认会扫描所有的注解


 

在Spring的配置文件中,可以使用来指定不扫描注解:@Controller和@ControllerAdvice

use-default-filters="false" 这个别忘记改成false,就是不使用默认的扫描规则,默认会扫描所有的注解


 

6、SpringMVC的IOC容器和Spring的IOC容器的关系 

       servlet:代表的的容器为spring-mvc的子容器,而DispatcherServlet 是前端控制器,该容器专门为前端监听请求的时候所用,就是说当接收到url请求的时候会引用springmvc容器内的对象来处理。

       context-param:代表的容器是spring本身的容器,spring-mvc可以理解为一个继承自该容器的子容器,spring容器是最顶层的父类容器,跟java的继承原理一样

       SpringMVC 的 IOC 容器中的 bean 可以引用Spring IOC 容器中的 bean;反之, Spring IOC 容器中的bean则不能引用Spring MVC IOC容器中的 bean 。因为:Spring MVC IOC容器是Spring IOC容器的子类,子类可以引用父类,父类不能引用子类。

       从软件层面上来说,Spring MVC是展示层可以调用业务层,业务层不能调用展示层。

      当服务器解析web.xml的时候由于listener监听的原因,会优先初始化spring容器,之后才初始化spring-mvc容器。

       Spring MVC WEB 层容器可作为 “业务层” Spring容器的子容器:即 WEB 层容器可以引用业务层容器的 Bean,而业务层容器却访问不到 WEB 层容器的 Bean(也就是说不能在Service或Dao中注入Controller)。

       注意:当Spring的IOC容器和SpringMVC的IOC容器的扫描包,可以扫描到相同的Controller和Service的时候,并且没有使用来排除某个注解的时候,Spring的IOC容器是可以访问SpringMVC的IOC容器中的Bean的(也就是可以在Service或Dao中引用Controller(使用注解@Autowired注入))。但是正式环境中,一般不会出现SpringMVC和Spring重复初始化同一个类的情况,所以不要在service和dao中注入Controller。


标签:

上一篇: zTree的简单使用1.0 下一篇:
素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。