Spring和SpringMVC整合及關系


SpringMVC扼要的講,就是控制請求和處理。有必要將Spring和SpringMVC整合,否則僅配置SpringMVC並完成Spring的功能,會造成業務邏輯混亂。

簡要總結:①原理:采用監聽器,可以在ServlertContext加載時,通過監聽器加載Spring的配置文件,創建Spring容器。②Spring提供的監聽器ContextLoaderListener (可以不用自己創建監聽器)。下面為詳細分析:

1、整合分析(模擬原理,SpringMVC可以通過在web.xml中直接配置監聽器):

  ①在配置文件中加入Spring的配置文件。但需要考慮,web容器啟動以后,Spring的配置文件不會自動加載。加載需要ApplicationContext調用其實現類ClassPathXmlApplicationContext的構造方法,實現Spring配置文件的加載。

  ②Spring配置文件什么時候加載?怎么加載?

Spring配置文件的一定需要在web項目啟動時加載,而且必須在Servlet配置前加載(為控制層的自動裝載做准備,SpringMVC所管理的控制層依賴於Spring管理的service業務邏輯層)。采用監聽器Listener(監聽在web程序執行中的一些事件,比如ServletContext的生命周期,或者某一屬性是否變化,監聽的是一個動作)。ServlertContext,在web項目啟動時就會創建。因此,可以創建一個監聽器,來監聽ServletContext的生命周期,一旦ServletContext創建,就去加載Spring的配置文件

注意的問題:

  1)SpringMVC和Spring配置文件,如果都配置包的掃描,可能會導致有的bean被創建2次。解決辦法,在Spring配置文件掃描中去除控制層的掃描:

    <context:component-scan base-package="com.atguigu">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

  2)在監聽器加載Spring配置文件時,在ServletContext中綁定ApplicationContext對象,從而能夠在控制層中使用Spring管理的bean。

package com.atguigu.listener;

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

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

/**
 * Application Lifecycle Listener implementation class SpringListener
 *
 */
public class SpringListener implements ServletContextListener {

    /**
     * Default constructor. 
     */
    public SpringListener() {
        // TODO Auto-generated constructor stub
    }

    /**
     * @see ServletContextListener#contextDestroyed(ServletContextEvent)
     */
    public void contextDestroyed(ServletContextEvent arg0)  { 
         // TODO Auto-generated method stub
    }

    /**
     * @see ServletContextListener#contextInitialized(ServletContextEvent)
     */
    public void contextInitialized(ServletContextEvent sce) { ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml"); ServletContext servletContext = sce.getServletContext(); servletContext.setAttribute("ac", ac); }
    
}
package com.atguigu.controller;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;

import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.atguigu.bean.Teacher;

@Controller
public class TestController {

 @RequestMapping("/testListener") //返回void,回去尋找與請求名一致的視圖,即testListener。但實際中不會有void的情況 public void testListener(HttpSession session) { //獲取spring所管理的teacher對象
        ServletContext servletContext = session.getServletContext(); ApplicationContext ac = (ApplicationContext)servletContext.getAttribute("ac"); Teacher teacher = ac.getBean("teacher", Teacher.class); System.out.println(teacher); }
        
}

Spring.xml

<?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-4.0.xsd">

    <!-- <bean id="user" class="com.atguigu.bean.User"></bean> -->
    <context:component-scan base-package="com.atguigu">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    
    <bean id="teacher" class="com.atguigu.bean.Teacher"></bean>

</beans>

 

2、SpringMVC配置:(建議使用)

  1)、包掃描(排除控制層)

  2)、配置監聽器 ContextLoaderListener


 

  <!-- needed for ContextLoaderListener ,該配置表示Spring的配置spring.xml文件在類路徑下,context-param標簽表示項目啟動時加載-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring.xml</param-value>
    </context-param>

    <!-- Bootstraps the root web application context before servlet initialization -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

注意:Spring的配置文件有默認的名字和位置,在WEB-INF文件下,名為applicationContext.xml

錯誤:BeanFactory not initialized or already closed,出現的三種情況:

  ①Spring的配置文件找不到(路徑或名稱不對)

  ②Spring的配置文件沒有創建

  ③Spring文件中出現了語法錯誤

 

Spring和SpringMVC關系

  Spring為父容器,SpringMVC為子容器。

  規定:子容器能夠調用訪問父容器中的bean,而父容器不能調用訪問子容器中的bean.

SpringMVC      |     Spring

Controller         |     service   dao

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM