Springmvc中的HandlerAdaptor执行流程
今天讲解一下在Springmvc中的HandlerAdaptor执行流程,明白这个过程,你就能画出下面的图:
接下来我们就来看看具体的实现过程吧。
1.0在DispatcherServlet中找到getHandlerAdapter()方法
2.0进入getHandlerAdapter()具体的方法实现内

3.0获取ModelAndView:

4.0真正的执行者:
简单地了解一下,还是用具体的代码来加强印象吧。
先把项目的架构搭建完成,依赖节点导入,进行下面的操作。
MAVEN所需的依赖节点:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<!--spring web jar 包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<!--springmvc jar 包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<!--spring-ormjar 包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
<!--servlet api包-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-spec</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
web.xml的配置:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation=" http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>Archetype Created Web Application</display-name> <!--中央调度器--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContextfirst.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
示例一:实现简单的访问
准备名称为FirstController的类
public class FirstController implements Controller{ /*第一个示例实现Controller接口*/ public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView av=new ModelAndView(); av.setViewName("index"); return av; } }
编写applicationfirst.xml:
<!--第一种方式实现-->
<!--处理器-->
<bean id="firstController" class="cn.happy.controller.FirstController"></bean>
<!--处理器映射器-->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello">firstController</prop>
</props>
</property>
</bean>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
效果图:
实例二:(注解方式)
@org.springframework.stereotype.Controller public class FirstController { /*第二个示例注解方式*/ @RequestMapping("1") public String index(){ return "index"; } @RequestMapping("2") public String index2(){ return "index2"; } }
applicationfirst.xml中的配置:
<!--第二种方式实现-注解-->
<!--配置包扫描器-->
<context:component-scan base-package="cn.happy.controller"></context:component-scan>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
现在项目中注解式开发还是不错的,简单,简洁。
效果图:


示例三:(根据不用访问名称来实现访问同一页面)
public class FirstController extends AbstractController{ /*不同的访问名称访问同一个方法*/ protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView av=new ModelAndView(); av.setViewName("index"); return av; } }
applicationfirst.xml中的配置:
<!--第三种实现方式 不同的访问名称AbstractResolver-->
<!--处理器-->
<bean id="firstController" class="cn.happy.controller.FirstController">
</bean>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--处理器映射器-->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/h1">firstController</prop>
<prop key="/h2">firstController</prop>
</props>
</property>
</bean>
效果图:


![]()
上图是接口Controller的实现类,我们可以很清晰的看到Controller-------->AbstractController------->MultiActionController,还有一些其他的子类,在这里我们就不一一介绍了,就拿MultiActionController为例。
上面的圈起来的两个类,就是方法名称解析所用到的。
先来第一种方式:PropertiesMethodNameResolver
public class FirstController extends MultiActionController{ /*继承MultiActionController propertiesMethodNameResolver*/ public ModelAndView doFirst(HttpServletRequest request, HttpServletResponse response) { ModelAndView av=new ModelAndView(); av.setViewName("index"); return av; } public ModelAndView doSecond(HttpServletRequest request, HttpServletResponse response){ ModelAndView av=new ModelAndView(); av.setViewName("index2"); return av; } }
applicationfirst.xml中的配置:
<!--第四种方式实现 第一种 MultiActionSesolver-->
<!--处理器-->
<bean id="firstController" class="cn.happy.controller.FirstController">
<!--关联方法名称解析器-->
<property name="methodNameResolver" ref="propertiesMethodNameResolver"></property>
</bean>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--处理器映射器-->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/*">firstController</prop>
</props>
</property>
</bean>
<!--方法名称解析器 PropertiesMethodNameResolver-->
<bean id="propertiesMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<prop key="/h1">doFirst</prop>
<prop key="/h2">doSecond</prop>
</props>
</property>
</bean>
效果图:

另一种方式:ParameterMethodNameResolver,先来一张图看一下
当你不指定paramName的时候默认为action
public class FirstController extends MultiActionController{ /*继承MultiActionController parameterMethodNameResolver*/ public ModelAndView doFirst(HttpServletRequest request, HttpServletResponse response) { ModelAndView av=new ModelAndView(); av.setViewName("index"); return av; } public ModelAndView doSecond(HttpServletRequest request, HttpServletResponse response){ ModelAndView av=new ModelAndView(); av.setViewName("index2"); return av; } }
applicationContextfirst.xml的配置:
<!--第四种方式实现 第二种 MultiActionSesolver-->
<!--处理器-->
<bean id="firstController" class="cn.happy.controller.FirstController">
<!--关联方法名称解析器-->
<property name="methodNameResolver" ref="parameterMethodNameResolver"></property>
</bean>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--处理器映射器-->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/*">firstController</prop>
</props>
</property>
</bean>
<!--方法名称解析器 PropertiesMethodNameResolver-->
<bean id="parameterMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
<property name="paramName" value="actionName"></property>
</bean>
指定了方法名称解析器的参数,效果图如下:

当注释掉之后,默认为action,效果图:
<!--方法名称解析器 PropertiesMethodNameResolver-->
<bean id="parameterMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
<!--<property name="paramName" value="actionName"></property>-->
</bean>

最后再来一组,访问外部资源和访问内部资源
public class FirstController extends MultiActionController{ public ModelAndView doFirst(HttpServletRequest request, HttpServletResponse response) { ModelAndView av=new ModelAndView(); av.setViewName("jd"); return av; } }
applicationContextfirst.xml的配置:
<!--外部资源方式-->
<!--处理器-->
<bean id="firstController" class="cn.happy.controller.FirstController">
<property name="methodNameResolver" ref="parameterMethodNameResolver"></property>
</bean>
<!--方法名称解析器-->
<bean id="parameterMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
</bean>
<!--处理器映射器-->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/*">firstController</prop>
</props>
</property>
</bean>
<!--外部资源-->
<bean id="jd" class="org.springframework.web.servlet.view.RedirectView">
<property name="url" value="http://www.jd.com"></property>
</bean>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"></bean>
在浏览器地址栏中填写如图所示地址:
内部资源访问:
只需要更改一处即可:
<!--外部资源-->
<bean id="jd" class="org.springframework.web.servlet.view.JstlView">
<property name="url" value="index2.jsp"></property>
</bean>
效果图:


浙公网安备 33010602011771号