首页 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
资讯 业界资讯 软件杂谈 编程开发 网站建设 网络观查 搜索引擎 移动应用 网站运营 网络地图
开发 移动开发 Web前端 架构设计 编程语言 互联网 数据库 系统运维 云计算 开发杂谈
[架构设计] 【转】spring Mvc 执行原理 及 xml注解配置说明
【转】spring Mvc 执行原理 及 xml注解配置说明

Spring MVC 执行原理
 在 Spring Mvc 访问过程里,每个请求都首先经过 许多的过滤器,经 DispatcherServlet chǔ理;
一个Spring MVC工程里,可以配置多个的 dispatcherServlet ,每个 DispatcherServlet 可以对应多个的 HandlerMapping ,每个 HandlerMapping 可以有自己的 Interceptor (拦截器)。
 


 
1. 请求首先 由 前端 DispatcherServlet 捕获;
2. DispatcherServlet 经过 HandlerMapping 获取适当的 Hanlder ,也即 Controller ,并返回给 DispatcherServlet;
3. 如果有设置 拦截器,首选执行拦截器的 preHandler 方法,并把执行结果返回 DispatcherServlet;
4. DispatcherServlet 根据捕获的请求,以及 Handler (Controller) ,获取到适当的 HandlerAdapter chǔ理,并把结果返回给 DispatcherServlet,结果为 (View 和 Model);
5. 如果有设置拦截器,就是执行 拦截器的 postHandler 方法,并返回 DispatcherServlet;
6. DispatcherServlet 根据获取的 view 跟 model 结合 ViewResolver,返回所指的 视图模板,并返回给 DispatcherServlet;
7. DispatcherServlet 结合 视图模型跟model ,执行 render() 渲染界面,并返回给客户端;
 
一个DispatcherServlet 都有自己 上下文配置文件, 这个配置继承自根的上下文配置文件;
每个 DispatcherServlet 都可配置多个不同的 HandlerMapping 映射方式;每个 HandlerMapping 都实现了 Ordered 接口,可以上下文文件配置中设置优先使用的 HandlerMapping;
用户的请求被 DispatcherServlet 捕获后,DispatcherServlet 使用优先级高的 HandlerMapping 查找可用的 Handler,如果没有找到合适的 Handler,就使优先级次之的 HandlerMapping 继续查找,直到找到为止;
比如:Spring MVC 提供主要的 HanderMapping 有 DefaultAnnotationHandlerMapping, SimpleUrlHandlerMapping, BeanNameUrlHandlerMapping
复制代码

<bean id="defaultAnnoHandlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="order" value="1"/>
</bean>

<bean id="simpleUrlMapping" class="org.
springframework.Web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="order" value="2"/>
    <!--  ... -->
</bean>

<bean id="beanNameUrlMapping" class="org.springframework.Web.servlet.
handler.BeanNameUrlHandlerMapping">
    <!-- ... -->
</bean>

复制代码

如果不为HandlerMapping明确指定order,那么默认值为Integer.MAX_VALUE,对应最低优先级。
如果 DefaultAnnotationHandlerMapping 找到相应的 Handler ,就把数据传给相应的 Controller 类下的相应的 HandlerAdapter (方法chǔ)chǔ理;如果没有找到,就到 SimpleUrlHandlerMapping chǔ理;


 
Spring MVC xml配置说明
 1. Web.xml 配置
1>. 首先 Spring 监听器:
<!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

它是整个 spring 框架的入口,会自动装载 应用程序根上下文的 配置文件;因为他实现了 ServletContextListener 这个接口,项目启动时,就会执行它实现的方法。
2>. 根应用程序上下文配置:
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml</param-value>
    </context-param>

也可jiào spring 全局配置,在这里可以配置 数据源 等一些 全局的spring 基本的配置;dispatcherServlet 可以继承自这里的配置;
3>. diapatcherServlet 配置:
复制代码

<!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
        
    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

复制代码

load-on-startup 值为 "1" 表示该 servlet (dispatcherServlet 也是一个 servlet) 随 servlet 容器同时启动。
dispatcherservlet 的 init-param 节点不是必须的,如果没有配置,该 dispatcherServlet 对应的 上下文配置文件 就会到 /WEB-INF/[servlet-name]-servlet.xml 加载;
servlet-mapping 的 url-pattern 的值 "*.do" 表示,servlet 只会拦截 .do 后缀的请求,这种配置不会影响静态资源的访问。
4>. 配置工程项目编码:
复制代码

<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>

复制代码

该过滤器如果没有配置,请求访问可能会遇luàn码;
-------------------------------------------------------------
现在配置 diapatcherServlet 对应的 上下文配置文件: /WEB-INF/spring/appServlet/servlet-context.xml (上面配置的)
1>.  启动扫描所有的 Controller
<context:component-scan base-package="com.study.web"/>

主要作用于 @Controller,假如他的包结构是这样的:
com.study.web
|---controller
|-----|-----abcController.java
   |-----cdeController.java
那么上面的 base-package 写为 com.study.web.controller 也是正确的;
 
2>. <mvc:annotation-driven /> 说明:
是一种简写形式,可以让初学者快速成应用默认的配置方案,会默认注册 DefaultAnnotationHandleMapping以及AnnotionMethodHandleAdapter 这两个 Bean, 这两个 Bean ,前者对应类级别, 后者对应到方法级别;
上在面的 DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter 是 Spring 为 @Controller 分发请求所必需的。
annotation-driven 扫描指定包中类上的注解,常用的注解有:
复制代码

@Controller 声明Action组件
@Service 声明Service组件 @Service("myMovieLister")
@Repository 声明Dao组件
@Component 泛指组件, 当不好归类时.
@RequestMapping("/menu") 请求映射
@Resource 用于注入,( j2ee提供的 ) 默认按名称装配,@Resource(name="beanName")
@Autowired 用于注入,(srping提供的) 默认按类型装配
@Transactional( rollbackFor={Exception.class}) 事务管理
@ResponseBody
@Scope("prototype") 设定bean的作用域

复制代码

 
3>. 视图解析类,对模型视图名称的解析,在请求时模型视图名称添加前后缀
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

InternalResourceViewResolver 提供了对 JstlView 的支持: <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> 
Spring Mvc 2.5 版本以前,提供了 注解 功能,实现了对 REST 的全面支持; REST 通过不带扩展名的 URL 来访问系统资源;REST 会把每个请求资源当成是静态,每个 URL 资源都是一个静态资源;
它通 @RequestMapping主@PathVariable 注释提供访问映射,由@RequestMapping 中的 value 及 method 就可以支持Rest式的访问。
通过策略接口,Spring 框架是高度可配置的,而且包含多种视图技术,例如 JavaServer Pages(JSP)技术、Velocity、Tiles、iText 和 POI。Spring MVC 框架并不知道使用的视图,所以不会强迫您只使用 JSP 技术。Spring MVC 分离了控制器、模型对象、分派器以及chǔ理程序对象的角sè,这种分离让它们更容易进行定制。
比如 使用的是 Velocity 技术,那么只要把 suffix 的 value 值改为 ".vm" 即可;
 
4>.  Spring 拦截器:
全局配置:
<mvc:interceptors>

        <bean class="com.study.web.interceptor.MyInterceptor"></bean>

</mvc:interceptors>

基于路径的拦截器:
复制代码

<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**/*.do"/>
            <beans:bean class="com.study.interceptor.utils.StuInterceptor">
                <beans:property name="startWrk">
                    <beans:value>1</beans:value>
                </beans:property>
                
                <beans:property name="endWrk">
                    <beans:value>24</beans:value>
                </beans:property>
                
                <beans:property name="redirectUrl">
                    <beans:value>http://127.0.0.1:8080/interceptor/static/timeout.htm</beans:value>
                </beans:property>
            </beans:bean>
        </mvc:interceptor>
    </mvc:interceptors>

复制代码

相关的 Java 类 : StuInterceptor ( 该类的作用是拦截在指定的时间范围外,则页面请求转到/interceptor/static/timeout.htm )
复制代码

package com.study.interceptor.utils;

import java.util.Calendar;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
//import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.study.interceptor.controller.HomeController;

public class StuInterceptor  implements HandlerInterceptor /*extends HandlerInterceptorAdapter*/ {
    
    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
    
    private int startWrk;
    private int endWrk;
    private String redirectUrl;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logger.info("Interceptor", "I am in Custom Interceptor!");
        
        Calendar cal = Calendar.getInstance();
        
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        
        if (hour > startWrk && hour < endWrk) {
            return true;
        } else {
            response.sendRedirect(redirectUrl);
            return false;
        }
    }
    
    public int getStartWrk() {
        return this.startWrk;
    }
    
    public void setStartWrk(int startWrk) {
        this.startWrk = startWrk;
    }
    
    public int getEndWrk() {
        return this.endWrk;
    }
    
    public void setEndWrk(int endWrk) {
        this.endWrk = endWrk;
    }
    
    public String getRedirectUrl() {
        return this.redirectUrl;
    }
    
    public void setRedirectUrl(String redirectUrl) {
        this.redirectUrl = redirectUrl;
    }

    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("after posthandler");  
    }

    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println("after completion");  
    }
}

复制代码

5>. 在 HandlerMapping 内配置拦截器:
复制代码

<!-- Mapping -->  
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">  
    <property name="mappings">  
        <props>  
            <prop key="/abc.do">abcController</prop>  
            <prop key="def.kara">defController</prop>   
        </props>  
    </property>  
    <!-- 注册拦截器 -->  
    <property name="interceptors">  
        <list>  
            <ref bean="myInterceptor"></ref>  
        </list>  
    </property>  
</bean>  

复制代码

复制代码

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> 
<property name="interceptors"> 
<list> 
<bean class="com.study.web.MyInteceptor"></bean> 
</list> 
</property> 
</bean>

复制代码

6>. 使用 placeHolder 加载应用程序属xìng配置文件
<context:property-placeholder location="/WEB-INF/config.properties"/>

比如 加载 mysql jdbc 配置信息:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/springdb
username=root
password=123

那么 mysql 的数据源配置的 驱动信息,用户信息,就可以配置成这样:
复制代码

<context:property-placeholder location="classpath:META-INF/mybatis/mysql.properties" />
    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${driver}"></property>
        <property name="url" value="${url}"></property>
        <property name="username" value="${username}"></property>
        <property name="password" value="${password}"></property>
    </bean>

复制代码



 此文从网络中自动搜索生成,不代表本网站赞成被搜索网站的内容或立场    查看原文
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 新闻资讯 小游戏 Chinese Culture 股票 三丰软件 开发 中国文化 网文精选 阅读网 看图 日历 万年历 2018年9日历
2018-9-22 12:52:47
 
  网站联系 软件世界网-www.sjsjw.com ©2014 蜀ICP备06016416号 三峰网旗下网站