zoukankan      html  css  js  c++  java
  • 第一节:Spring 与 SpringMVC 整合

    一、Spring 与 SpringMVC 是否需要整合?

      1、需要进行 Spring 整合 SpringMVC 吗?
      2、还是否需要再加入 Spring 的 IOC 容器?
      3、是否需要再 web.xml 文件中配置启动的 Spring IOC 容器的 ContextLoaderListener?

      不需要整合:

        都放在 SpringMVC 的配置文件中,也可以分多个 Spring 的配置文件,然后使用 import 节点导入其他的配置文件

        示例:在 springmvc.xml 中导入 spring.xml 文件

        <import resource="spring.xml"/>

         不整合造成的问题:需要将 spring 管理的内容都交给 springMVC 管理,这样会造成业务逻辑混乱

      需要整合:

        通常情况下,类似于数据源、事务,整合其他框架都是放在 Spring 的配置文件中(而不是放在 SpringMVC 的配置文件中),实际上放入 Spring 配置文件对应的 IOC 容器中的还有 Service 和 Dao。

        整合的目的:分工明确

          SpringMVC的配置文件就来配置网站转发逻辑以及网站功能有关的(视图解析器、文件上传解析器、支持ajax)

          Spring的配置文件来配置和业务有关的(事务控制,数据源,xxx)

        

        整合:Spring 的配置文件在什么时候加载?怎么加载?

        注意:Spring 的配置文件必须在项目启动时加载,且要在 Servlet 加载前加载。

        解决方法:使用监听器(首先执行),可以在ServletContext 加载时,通过监听器加载 Spring 的配置文件,创建 Spring 容器,也可以使用 Spring 提供的监听器。

     

    二、准备工作

      1、创建一个动态 Web 工程

      2、导入 jar 包依赖

       <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <spring-version>4.1.0.RELEASE</spring-version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.1.3</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-expression</artifactId>
                <version>${spring-version}</version>
            </dependency>
    
            <!--  AOP  -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${spring-version}</version>
            </dependency>
    
            <!--  Web  -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring-version}</version>
            </dependency>
    
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
    
    
            <dependency>
                <groupId>org.apache.taglibs</groupId>
                <artifactId>taglibs-standard-impl</artifactId>
                <version>1.2.1</version>
            </dependency>
            <dependency>
                <groupId>org.apache.taglibs</groupId>
                <artifactId>taglibs-standard-spec</artifactId>
                <version>1.2.1</version>
            </dependency>
    
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-validator</artifactId>
                <version>5.2.4.Final</version>
            </dependency>
    
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
                <version>2.9.8</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
                <version>2.9.8</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.9.8</version>
            </dependency>
    
    
        </dependencies>

      3、创建 Spring 的配置文件 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.xsd">
    
    
        <!--扫描组件,排除 controller 和 ControllerAdvice-->
        <context:component-scan base-package="com.njf" use-default-filters="true">
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
            <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
        </context:component-scan>

    <!-- 配置数据源,整合其他框架,事务等等 -->
    </beans>

      4、配置 springMVC的配置文件 springmvc.xml(只扫描控制器和异常处理,和web相关的组件)

    <?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/mvc  http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
             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">
        <!-- 扫描组件,将加上@Controller注解的类作为springMVC的控制层和异常控制器 -->
        <context:component-scan base-package="com.njf" use-default-filters="false">
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
            <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
        </context:component-scan>
         
         <!--  配置一个视图解析器 :能帮我们拼接页面地址-->
         <bean  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
             <property name="prefix"  value="/WEB-INF/view/"></property>
             <property name="suffix"  value=".jsp"></property>
         </bean>
         
         <!-- 处理静态资源,交给 Tomcat 处理 -->
         <mvc:default-servlet-handler/>
         
         <!-- 开启 SpringMVC 的高级功能 -->
         <mvc:annotation-driven />
         
         <!--
             处理文件,将客户端上传的File文件,处理为MultipartFile
             注意:文件解析器的bean中id必须设置为multipartResolver
          -->
         <bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
             <!-- 设置文件解析的编码,注意:一定要和页面的pageEncoding保持一致 -->
             <property name="defaultEncoding"  value="UTF-8"></property>
             <!-- 设置最大上传文件大小 -->
             <property name="maxUploadSize"  value="88888888"></property>
         </bean>
         
         <!-- 配置异常处理器 -->
         <bean  class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
             <property name="exceptionMappings">
                  <props>
                      <prop  key="java.lang.NullPointerException">error</prop>
                  </props>
             </property>
         </bean>
    
         <!-- <mvc:interceptors>
             默认拦截所有请求
             <bean  class="com.spring.interceptor.FirstInterceptor"></bean>
             <bean  class="com.spring.interceptor.SecondInterceptor"></bean>
             此方式要求拦截器类上必须加注解@Component
             <ref bean="firstInterceptor"/>
             
             设置自定义拦截方式
             <mvc:interceptor>
                  <bean></bean>
                  <mvc:mapping path=""/>
                  <mvc:exclude-mapping path=""/>
             </mvc:interceptor>
         </mvc:interceptors> -->
    </beans>

      5、存在的问题

        若 Spring 的 IOC 容器和 SpringMVC 的 IOC 容器扫描的包有重合的部分,就会导致有的 bean 会被创建两次。
        如果某个包下面的 bean 会被扫描多次,就会出现多个 bean 的问题。

      6、解决方案

        使用 Spring 的 IOC 容器扫描的包和 SpringMVC 的 IOC 容器扫描的包没有重合的部分,可以使用 exclude-filter 和 include-filter 子节点来规定只能扫描的注解:

        由于 SpringMVC 是对 Servlet 的封装,我们可以只用来扫描控制层;

        spring 的配置文件扫描除了控制层之外的 bean,还可以用于配置数据源,整合其他框架,事务等;

        具体配置如上。

    三、自定义监听器整合Spring与SpringMVC

      1、自定义监听器

    public class SpringListener implements ServletContextListener {
    
        public SpringListener() {
        }
    
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            //获取 application 对象
            ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
            ServletContext servletContext = sce.getServletContext();
            // 把spring IOC 容器放到 application 域中
            servletContext.setAttribute("ac", ac);
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
    
        }
    }

      2、web.xml 中的配置

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
             version="3.0">
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
            <welcome-file>index.html</welcome-file>
            <welcome-file>index.htm</welcome-file>
            <welcome-file>default.jsp</welcome-file>
            <welcome-file>default.html</welcome-file>
            <welcome-file>default.htm</welcome-file>
        </welcome-file-list>
    
        <!-- 配置自定义的监听器 -->
        <listener>
            <listener-class>com.njf.listener.SpringListener</listener-class>
        </listener>
    
        <!--  前端控制器(核心控制器)  -->
        <servlet>
            <servlet-name>DispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!-- 配置DispatcherServlet的初始化參數:设置文件的路径和文件名称 -->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc.xml</param-value>
            </init-param>
            <!--
               servlet 启动加载,servlet 原本是第一次访问创建对象
               load-on-startup:服务器启动的时候就创建对象,值越小优先级越高,越先创建对象
             -->
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <!--
          /* 和 / 都是拦截所有请求,/:会拦截所有请求,但是不会拦截 *.jsp,能保证 jsp访问正常;
          /* 的范围更大,还会拦截 *.jsp 这些请求,一旦拦截 jsp 页面就不能显示了
        -->
        <servlet-mapping>
            <servlet-name>DispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>     <!-- / 这样写,只有请求才处理,页面会过滤掉 -->
        </servlet-mapping>
    
    
        <!--  字符编码过滤器  -->
        <filter>
            <filter-name>characterEncodingFilter</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <!-- 设置字符编码 -->
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
            <!-- 强制设置响应进行编码 -->
            <init-param>
                <param-name>forceEncoding</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>characterEncodingFilter</filter-name>
            <url-pattern>/*</url-pattern>  <!-- 对所有的请求都拦截,处理所有响应-->
        </filter-mapping>
    
        <!-- REST 风格过滤器-->
        <filter>
            <filter-name>HiddenHttpMethodFilter</filter-name>
            <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>HiddenHttpMethodFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
    </web-app>

      3、控制器方法

        @RequestMapping(value = "/hello2")
        public String hello2(HttpSession session) {
            //获取spring IOC 所管理的 bean 组件
            ServletContext servletContext = session.getServletContext();
            ApplicationContext ac = (ApplicationContext)servletContext.getAttribute("ac");
            System.out.println(ac);
            BookService bookService = ac.getBean("bookService", BookService.class);
            System.out.println("bookService = " + bookService);
            return "success";
        }

        可以在控制器方法中通过 ServletContext 对象来获取 application 对象,从而进行操作。

     

    四、使用Spring监听器进行整合

      1、使用 Spring 监听器

        在 web.xml 中进配置

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
             version="3.0">
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
            <welcome-file>index.html</welcome-file>
            <welcome-file>index.htm</welcome-file>
            <welcome-file>default.jsp</welcome-file>
            <welcome-file>default.html</welcome-file>
            <welcome-file>default.htm</welcome-file>
        </welcome-file-list>
    
         <!-- 配置启动 Spring IOC容器的 Listener-->
         <listener>
             <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
         </listener>
    
        <!--  前端控制器(核心控制器)  -->
        <servlet>
            <servlet-name>DispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!-- 配置DispatcherServlet的初始化參數:设置文件的路径和文件名称 -->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc.xml</param-value>
            </init-param>
            <!--
               servlet 启动加载,servlet 原本是第一次访问创建对象
               load-on-startup:服务器启动的时候就创建对象,值越小优先级越高,越先创建对象
             -->
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <!--
          /* 和 / 都是拦截所有请求,/:会拦截所有请求,但是不会拦截 *.jsp,能保证 jsp访问正常;
          /* 的范围更大,还会拦截 *.jsp 这些请求,一旦拦截 jsp 页面就不能显示了
        -->
        <servlet-mapping>
            <servlet-name>DispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>     <!-- / 这样写,只有请求才处理,页面会过滤掉 -->
        </servlet-mapping>
    
    
        <!--  字符编码过滤器  -->
        <filter>
            <filter-name>characterEncodingFilter</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <!-- 设置字符编码 -->
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
            <!-- 强制设置响应进行编码 -->
            <init-param>
                <param-name>forceEncoding</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>characterEncodingFilter</filter-name>
            <url-pattern>/*</url-pattern>  <!-- 对所有的请求都拦截,处理所有响应-->
        </filter-mapping>
    
        <!-- REST 风格过滤器-->
        <filter>
            <filter-name>HiddenHttpMethodFilter</filter-name>
            <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>HiddenHttpMethodFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
    </web-app>

        但是这是会在控制台报错:

    java.lang.IllegalStateException: BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext

        这是因为没有找到 spring 的配置文件(可能是文件名错误或路径错误)

        还需要在 web.xml中 配置 <context-param> 标签,指定 spring.xml 的位置

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
             version="3.0">
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
            <welcome-file>index.html</welcome-file>
            <welcome-file>index.htm</welcome-file>
            <welcome-file>default.jsp</welcome-file>
            <welcome-file>default.html</welcome-file>
            <welcome-file>default.htm</welcome-file>
        </welcome-file-list>
    
        <!-- 配置 spring 容器,指定 spring 的配置文件 spring.xml-->
        <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:spring.xml</param-value>
        </context-param>
    
         <!-- 配置启动 Spring IOC容器的 Listener-->
         <listener>
             <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
         </listener>
    
        <!--  前端控制器(核心控制器)  -->
        <servlet>
            <servlet-name>DispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!-- 配置DispatcherServlet的初始化參數:设置文件的路径和文件名称 -->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc.xml</param-value>
            </init-param>
            <!--
               servlet 启动加载,servlet 原本是第一次访问创建对象
               load-on-startup:服务器启动的时候就创建对象,值越小优先级越高,越先创建对象
             -->
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <!--
          /* 和 / 都是拦截所有请求,/:会拦截所有请求,但是不会拦截 *.jsp,能保证 jsp访问正常;
          /* 的范围更大,还会拦截 *.jsp 这些请求,一旦拦截 jsp 页面就不能显示了
        -->
        <servlet-mapping>
            <servlet-name>DispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>     <!-- / 这样写,只有请求才处理,页面会过滤掉 -->
        </servlet-mapping>
    
    
        <!--  字符编码过滤器  -->
        <filter>
            <filter-name>characterEncodingFilter</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <!-- 设置字符编码 -->
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
            <!-- 强制设置响应进行编码 -->
            <init-param>
                <param-name>forceEncoding</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>characterEncodingFilter</filter-name>
            <url-pattern>/*</url-pattern>  <!-- 对所有的请求都拦截,处理所有响应-->
        </filter-mapping>
    
        <!-- REST 风格过滤器-->
        <filter>
            <filter-name>HiddenHttpMethodFilter</filter-name>
            <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>HiddenHttpMethodFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
    </web-app>

        如果没有配置此标签,监听器默认会去 web-content 下找 application.xml的配置文件,找不到,就会报上面的错误,如果使用了该标签,就可以指定配置文件的路径和名称了。

        扩展:web.xml中的执行顺序
        1、首先加载的是 <context-parm> ,里面存放的当前 web 应用的参数和配置
        2、运行监听器
        3、运行过滤器
        4、运行 Servlet
    

      

      2、ContextLoaderListener 部分源码

    public class ContextLoaderListener extends  ContextLoader implements ServletContextListener {
       
         public ContextLoaderListener() {
         }
        
         public ContextLoaderListener(WebApplicationContext  context) {
             super(context);
         }
        
         @Override
         public void contextInitialized(ServletContextEvent  event) {
             initWebApplicationContext(event.getServletContext());
         }
        
         @Override
         public void contextDestroyed(ServletContextEvent  event) {
             closeWebApplicationContext(event.getServletContext());
             ContextCleanupListener.cleanupAttributes(event.getServletContext());
         }
    }
    
    
    initWebApplicationContext 方法源码:
    
        public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
            if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
                throw new IllegalStateException(
                        "Cannot initialize context because there is already a root application context present - " +
                        "check whether you have multiple ContextLoader* definitions in your web.xml!");
            }
    
            Log logger = LogFactory.getLog(ContextLoader.class);
            servletContext.log("Initializing Spring root WebApplicationContext");
            if (logger.isInfoEnabled()) {
                logger.info("Root WebApplicationContext: initialization started");
            }
            long startTime = System.currentTimeMillis();
    
            try {
                // Store context in local instance variable, to guarantee that
                // it is available on ServletContext shutdown.
                if (this.context == null) {
                    this.context = createWebApplicationContext(servletContext);
                }
                if (this.context instanceof ConfigurableWebApplicationContext) {
                    ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
                    if (!cwac.isActive()) {
                        // The context has not yet been refreshed -> provide services such as
                        // setting the parent context, setting the application context id, etc
                        if (cwac.getParent() == null) {
                            // The context instance was injected without an explicit parent ->
                            // determine parent for root web application context, if any.
                            ApplicationContext parent = loadParentContext(servletContext);
                            cwac.setParent(parent);
                        }
                        configureAndRefreshWebApplicationContext(cwac, servletContext);
                    }
                }
                servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
    
                ClassLoader ccl = Thread.currentThread().getContextClassLoader();
                if (ccl == ContextLoader.class.getClassLoader()) {
                    currentContext = this.context;
                }
                else if (ccl != null) {
                    currentContextPerThread.put(ccl, this.context);
                }
    
                if (logger.isDebugEnabled()) {
                    logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +
                            WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
                }
                if (logger.isInfoEnabled()) {
                    long elapsedTime = System.currentTimeMillis() - startTime;
                    logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
                }
    
                return this.context;
            }
            catch (RuntimeException ex) {
                logger.error("Context initialization failed", ex);
                servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
                throw ex;
            }
            catch (Error err) {
                logger.error("Context initialization failed", err);
                servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
                throw err;
            }
        }

    五、父子容器

      Spring Ioc 容器 与 SpringMVC Ioc 容器的关系
      SpringMVC 的 Ioc 容器中的 bean 可以来应用 Spring Ioc 容器中的 bean,返回来却不行!Spring Ioc 容器中的 bean 却不能引用 SpringMVC Ioc 容器中的 bean。
      spring 是父容器,springMVC 是子容器
     
      规定:子容器能够调用访问父容器中的 bean,而父容器不能够调用访问子容器中的 bean
     
      1、在 SpringMVC 配置文件中引用业务层的 Bean;
      2、多个 Spring IOC容器之间设置为父子关系,以实现良好的解耦;
      3、SpringMVC WEB 层容器可作为 “业务层”,Spring 容器的子容器:即 WEB 层容器可以引用业务层容器的 Bean,而业务层容器却访问不到 WEB 层容器的 Bean;
      
      Spring 管理业务逻辑组件
      SpringMVC 管理控制器组件

    六、SpringMVC 对比 Struts2

        1、SpringMVC 的入口是 Servlet,而 Struts2 是Filter;
        2、SpringMVC 会稍微比 Struts2 快些,SpringMVC 是基于方法设计,而 Struts2 是基于类,每次发送一次请求都会实例一个 Action;
        3、SpringMVC 使用更加简洁,开发效率 SpringMVC确实比 struts2 高,支持 JSR303,处理 AJAX 的请求更方便;
        4、 Struts2 的 OGNL 表达式使页面的开发效率相比 Spring MVC 更高些;
     
     
  • 相关阅读:
    第四次实验报告
    第三次实验报告
    第五章 循环结构课后反思
    第二次实验报告
    5-508寝室第六小组课后习题作业
    第一次实验报告
    第九章 构造数据类型实验
    第八章 指针实验
    第七章 数组实验
    第六章 函数和宏定义实验(2)
  • 原文地址:https://www.cnblogs.com/niujifei/p/15661522.html
Copyright © 2011-2022 走看看