Spring和SpringMVC整合出现的问题:

原因

SpringMVC就运行在Spring环境之下,为什么还要整合呢?SpringMVC和Spring都有IOC容器,是不是都需要保留呢?

通常情况下,类似于数据源,事务,整合其他框架都是放在spring的配置文件中(而不是放在SpringMVC的配置文件中),实际上放入Spring配置文件对应的IOC容器中的还有Service和Dao.而SpringMVC也搞自己的一个IOC容器,在SpringMVC的容器中只配置自己的Handler(Controller)信息。所以,两者的整合是十分有必要的,SpringMVC负责接受页面发送来的请求,Spring框架则负责整理中间需求逻辑,对数据库发送操作请求,对数据库的操作目前则先使用Spring框架中的JdbcTemplate进行处理。

目录结构

详细结构

applicationContext.xml

123456789101112
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">    <!--spring的配置文件-->    <bean id="person" class="com.hph.ss.beans.Person">        <property name="name" value="Spring+SpringMVC"></property>    </bean>    <!-- 组件扫描 --> <context:component-scan base-package="com.hph.ss"></context:component-scan></beans>

Person

123456789101112131415161718
package com.hph.ss.beans;

public class Person {    private String name;

    public String getName() {        return name;    }

    public void setName(String name) {        this.name = name;    }

    public void sayHello() {        System.out.println("My name is " + name);    }

}

UserDao

12345678910111213
package com.hph.ss.dao;

import org.springframework.stereotype.Repository;

@Repositorypublic class UserDao {    public UserDao(){        System.out.println("UserDao....");    }    public void hello() {        System.out.println("UserDao  hello.....");    }}

UserHandler

1234567891011
package com.hph.ss.handler;

import org.springframework.stereotype.Controller;

@Controllerpublic class UserHandler {

    public UserHandler() {        System.out.println("UserHandler.......");    }}

MyServletContextlistener

123456789101112131415161718192021222324252627
package com.hph.ss.listerner;

import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.servlet.ServletContext;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;

public class MyServletContextlistener implements ServletContextListener {    /**     * 当监听到ServletContext被创建,则执行该方法     */    public void contextInitialized(ServletContextEvent sce) {        //1.创建SpringIOC容器对象        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        //2.将SpringIOC容器对象绑定到ServletContext中        ServletContext sc = sce.getServletContext();

        sc.setAttribute("applicationContext", ctx);    }

    public void contextDestroyed(ServletContextEvent sce) {

    }}

UserService

1234567891011121314151617181920
package com.hph.ss.service;

import com.hph.ss.dao.UserDao;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;

@Servicepublic class UserService {

  @Autowired   private UserDao userDao  ;

  public UserService() {        System.out.println("UserService ......");   }

  public void hello() {     userDao.hello();  }}

HelloServlet

1234567891011121314151617181920212223242526272829303132
package com.hph.ss.servlet;

import com.hph.ss.beans.Person;import org.springframework.context.ApplicationContext;

import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;

@WebServlet(name = "HelloServlet")public class HelloServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        //访问到SpringIOC容器中的person对象.        //从ServletContext对象中获取SpringIOC容器对象        ServletContext sc = getServletContext();

        ApplicationContext ctx = (ApplicationContext) sc.getAttribute("applicationContext");

        Person person = ctx.getBean("person", Person.class);        person.sayHello();

    }}

springmvc.xml

1234567891011121314151617
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xmlns:mvc="http://www.springframework.org/schema/mvc"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">    <!--组件扫描-->    <context:component-scan base-package="com.hph.ss"></context:component-scan>    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="prefix" value="WEB-INF/views/"></property>        <property name="suffix" value=".jsp"></property>    </bean>    <!--处理静态资源-->    <mvc:default-servlet-handler/>    <mvc:annotation-driven/></beans>

web

index.jsp

123456789
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html>  <head>    <title>$Title$</title>  </head>  <body>  <a href="hello">Hello Springmvc</a>  </body></html>

web. xml

1234567891011121314151617181920212223242526272829303132
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"         version="4.0">    <!-- 初始化SpringIOC容器的监听器 -->    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>classpath:applicationContext.xml</param-value>    </context-param>

    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>

    <!-- Springmvc的前端控制器 -->    <!-- The front controller of this Spring Web application, responsible for handling all application requests -->    <servlet>        <servlet-name>springDispatcherServlet</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <init-param>            <param-name>contextConfigLocation</param-name>            <param-value>classpath:springmvc.xml</param-value>        </init-param>        <load-on-startup>1</load-on-startup>    </servlet>    <!-- Map all requests to the DispatcherServlet for handling -->    <servlet-mapping>        <servlet-name>springDispatcherServlet</servlet-name>        <url-pattern>/</url-pattern>    </servlet-mapping></web-app>

问题

原因:

问题描述

Spring集成SpringMVC启动后同一个bean注入了两次

原因分析

Sping+SpringMVC的框架中,IoC容器的加载过程:

  1. 基本上Web容器(如Tomcat)先加载ContextLoaderListener,然后生成一个IoC容器。
  2. 然后再实例化DispatchServlet时候会加载对应的配置文件,再次生成Controller相关的IoC容器。

关于上面两个容器关系:

ContextLoaderListener中创建ApplicationContext主要用于整个Web应用程序需要共享的一些组件,比如DAO,数据库的ConnectionFactory等。而由DispatcherServlet创建的ApplicationContext主要用于和该Servlet相关的一些组件,比如Controller、ViewResovler等。

对于作用范围而言,在DispatcherServlet中可以引用由ContextLoaderListener所创建的ApplicationContext,而反过来不行。

解决方法

方法1

springmvc.xml

12
<!--组件扫描--><context:component-scan base-package="com.hph.ss.handler"></context:component-scan>

applicationContext.xml

1
<context:component-scan base-package="com.hph.ss.dao,com.hph.ss.service"></context:component-scan>

方法2

springmvc.xml

12345
<!--组件扫描--> <context:component-scan base-package="com.hph.ss" use-default-filters="false">     <context:include-filter type="annotation"                             expression="org.springframework.stereotype.Controller"></context:include-filter> </context:component-scan>

applicationContext.xml

1234
   <!-- 组件扫描 --><context:component-scan base-package="com.hph.ss">    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter></context:component-scan>

关系

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

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

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

在 Spring MVC 配置文件中引用业务层的 Bean

多个 Spring IOC 容器之间可以设置为父子关系,以实现良好的解耦。

Spring MVC WEB 层容器可作为 “业务层” Spring 容器的子容器:即 WEB 层容器可以引用业务层容器的 Bean,而业务层容器却访问不到 WEB 层容器的 Bean

Spring和SpringMVC整合相关推荐

  1. SSM整合(1): spring 与 springmvc 整合

    久没有写博客了, 今年事情太多了, 也没了心思. 去深圳出差,  更重要的结婚的事情, 一茬接一茬. 好在最近闲暇一些, 就想记录一些曾经困扰过我的问题(现在用spring boot真是太方便了, 很 ...

  2. 【Spring】SpringMVC整合JPA

    这篇文章是在SpringMVC的基础上对数据持久层JPA的整合,实现了应用层和数据库的数据交互.在整合JPA前,请先参照下面第一篇博文搭建好SpringMVC框架. 一. 和本篇博文相关的一些基础知识 ...

  3. 【Spring+Mybatis+SpringMVC整合项目五】天猫商城(后台-订单管理开发)

    这里再记录订单管理的开发步骤.看看订单的POJO 里面包含了四个非数据库字段 private List<OrderItem> orderItems;private User user;pr ...

  4. SSM整合(2): spring 与 mybatis 整合

    在进行完spring与springmvc整合之后, 继续 spring与mybatis的整合. 既然是操作数据库, 那必然不能缺少了连接属性 一. db.properties jdbc.driver= ...

  5. 史上最详细的SSM框架整合(Spring、SpringMVC、Mybatis)

    毫无疑问我们肯定是使用Spring去整合SpringMVC和Mybatis,在整合过程中我们首先要让各自的模块实现,然后再去使用Spring整合:比如我先实现Mybatis框架的配置,然后再通过测试看 ...

  6. 配置spring、SpringMVC,mybatis进行整合

    springframwork的官网 spring-projects/spring-mvc-showcase https://github.com/spring-projects/spring-mvc- ...

  7. SpringMVC(2)—SpringMVC整合Spring的HelloWorld

    一.这是一个SpringMVC框架的案例HelloWorld 功能:HelloWorld 二.SpringMVC运行流程 1.流程 请求-->springDispatcherServlet的ur ...

  8. 孙宇java_[JAVA] 孙宇老师Struts2+Hibernate4+Maven+EasyUI+SpringMvc+Spring+Mybatis+Maven整合课程...

    资源介绍 孙宇老师Struts2+Hibernate4+Maven+EasyUI+SpringMvc+Spring+Mybatis+Maven整合课程 ===============课程目录===== ...

  9. java项目整合mybatis_JavaWeb项目整合Spring,SpringMVC,Mybatis框架

    衔接上篇: 版本信息 spring 4.4.13 mybatis 3.4.1 One Step! 根据所需,导入相应jar包,添加依赖. //spring 系列包 4.4.13 // spring m ...

最新文章

  1. solr单机版的搭建
  2. Memcache 内存分配策略和性能(使用)状态检查
  3. PolarFS :一个用于共享存储云数据库的超低延迟和容错分布式文件系统
  4. E-SKILL网络工程师考试认证必备
  5. vector function trmplate
  6. shell 脚本 自动化
  7. android中 MediaStore提取缩略图和原始图像
  8. SLAM Cartographer(2)ROS封装
  9. GNU Linux系统变量(sysctl配置命令)综合使用
  10. java udp多线程服务器_UDP服务端多线程-----
  11. 图像数字水印技术研究及matlab实现,数字水印技术研究及其matlab仿真.doc
  12. 【DC-DC开关电源芯片的使用(LM2596)】
  13. 计算机专业英语课程内容,《计算机专业英语》课程教学大纲
  14. java nginx 502_Nginx 中 502 和 504 错误详解
  15. 电脑重装系统找不到计算机了,戴尔电脑重装系统后找不到硬盘或找不到引导设备怎么办?...
  16. 软考真题答案-2021年5月系统集成项目管理工程师上午题
  17. JSP九大内置对象是什么?
  18. 【王道】倒可乐、广度优先算法
  19. 解读SEO 黑帽白帽 (share)
  20. 方少森:开源运维软件在小米的应用

热门文章

  1. Head First设计模式一:策略模式
  2. git grade 版本下载及安装
  3. Java迭代器的一般用法
  4. commonJS — 数字操作(for Number)
  5. 一个简单的动画FPS
  6. 基础编程题目集 6-6 求单链表结点的阶乘和 (15 分)
  7. 软件工程复习提纲——第八章
  8. oracle日期虚数0去掉,第 14 章 使用复数运算库
  9. mysql主从注意事项_mysql主从复制亲测,以及注意事项
  10. Oracle案例:深入解析ASM rebalance无法启动