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容器的加载过程:
- 基本上Web容器(如Tomcat)先加载ContextLoaderListener,然后生成一个IoC容器。
- 然后再实例化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整合相关推荐
- SSM整合(1): spring 与 springmvc 整合
久没有写博客了, 今年事情太多了, 也没了心思. 去深圳出差, 更重要的结婚的事情, 一茬接一茬. 好在最近闲暇一些, 就想记录一些曾经困扰过我的问题(现在用spring boot真是太方便了, 很 ...
- 【Spring】SpringMVC整合JPA
这篇文章是在SpringMVC的基础上对数据持久层JPA的整合,实现了应用层和数据库的数据交互.在整合JPA前,请先参照下面第一篇博文搭建好SpringMVC框架. 一. 和本篇博文相关的一些基础知识 ...
- 【Spring+Mybatis+SpringMVC整合项目五】天猫商城(后台-订单管理开发)
这里再记录订单管理的开发步骤.看看订单的POJO 里面包含了四个非数据库字段 private List<OrderItem> orderItems;private User user;pr ...
- SSM整合(2): spring 与 mybatis 整合
在进行完spring与springmvc整合之后, 继续 spring与mybatis的整合. 既然是操作数据库, 那必然不能缺少了连接属性 一. db.properties jdbc.driver= ...
- 史上最详细的SSM框架整合(Spring、SpringMVC、Mybatis)
毫无疑问我们肯定是使用Spring去整合SpringMVC和Mybatis,在整合过程中我们首先要让各自的模块实现,然后再去使用Spring整合:比如我先实现Mybatis框架的配置,然后再通过测试看 ...
- 配置spring、SpringMVC,mybatis进行整合
springframwork的官网 spring-projects/spring-mvc-showcase https://github.com/spring-projects/spring-mvc- ...
- SpringMVC(2)—SpringMVC整合Spring的HelloWorld
一.这是一个SpringMVC框架的案例HelloWorld 功能:HelloWorld 二.SpringMVC运行流程 1.流程 请求-->springDispatcherServlet的ur ...
- 孙宇java_[JAVA] 孙宇老师Struts2+Hibernate4+Maven+EasyUI+SpringMvc+Spring+Mybatis+Maven整合课程...
资源介绍 孙宇老师Struts2+Hibernate4+Maven+EasyUI+SpringMvc+Spring+Mybatis+Maven整合课程 ===============课程目录===== ...
- java项目整合mybatis_JavaWeb项目整合Spring,SpringMVC,Mybatis框架
衔接上篇: 版本信息 spring 4.4.13 mybatis 3.4.1 One Step! 根据所需,导入相应jar包,添加依赖. //spring 系列包 4.4.13 // spring m ...
最新文章
- solr单机版的搭建
- Memcache 内存分配策略和性能(使用)状态检查
- PolarFS :一个用于共享存储云数据库的超低延迟和容错分布式文件系统
- E-SKILL网络工程师考试认证必备
- vector function trmplate
- shell 脚本 自动化
- android中 MediaStore提取缩略图和原始图像
- SLAM Cartographer(2)ROS封装
- GNU Linux系统变量(sysctl配置命令)综合使用
- java udp多线程服务器_UDP服务端多线程-----
- 图像数字水印技术研究及matlab实现,数字水印技术研究及其matlab仿真.doc
- 【DC-DC开关电源芯片的使用(LM2596)】
- 计算机专业英语课程内容,《计算机专业英语》课程教学大纲
- java nginx 502_Nginx 中 502 和 504 错误详解
- 电脑重装系统找不到计算机了,戴尔电脑重装系统后找不到硬盘或找不到引导设备怎么办?...
- 软考真题答案-2021年5月系统集成项目管理工程师上午题
- JSP九大内置对象是什么?
- 【王道】倒可乐、广度优先算法
- 解读SEO 黑帽白帽 (share)
- 方少森:开源运维软件在小米的应用