SpringMVC 分析(一) handlerMapping 的初始化

来源:互联网 发布:网络语老干部什么意思 编辑:程序博客网 时间:2024/05/03 20:14

承接上文。

当然首先并没有去关注DispatcherServlet,而是首先关注了handlerMapping 的作用,纯粹是想知道一下是怎么去做mapping的。以后会去详细看DispatcherServlet。

初始化的过程是必须的。首先关注。

追根溯源,发现 其抽象类是AbstractHandlerMethodMapping 。好了,现在只关注handlerMapping ,至于其他东西的初始化忽略。看起init方法。真正初始化过程其实就是由这个init方法主导。

protected void initHandlerMethods() {
if (logger.isDebugEnabled()) {
logger.debug("Looking for request mappings in application context: " + getApplicationContext());
}
String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
getApplicationContext().getBeanNamesForType(Object.class));
for (String beanName : beanNames) {
if (isHandler(getApplicationContext().getType(beanName))){
detectHandlerMethods(beanName);
}
}
handlerMethodsInitialized(getHandlerMethods());
}

1.首先发现它会去获取 beanNames,debug一下,就是在spring的servlet配置文件中注册的一些bean还有@Controller注解过的一些Controller。

2.isHandler分别判断是否是Heandler,也就是是否是Controller。使用过@Controller或者@RequestMapping注解就行。

@Override
protected boolean isHandler(Class<?> beanType) {
return ((AnnotationUtils.findAnnotation(beanType, Controller.class) != null) ||
(AnnotationUtils.findAnnotation(beanType, RequestMapping.class) != null));
}

3.随后对Handler解析出所有需要分发的Methods。就是此Controller全部的方法。获取到全部方法之后 会对方法进行注册registerHandlerMethod

protected void detectHandlerMethods(final Object handler) {
Class<?> handlerType = (handler instanceof String) ?
getApplicationContext().getType((String) handler) : handler.getClass();
final Class<?> userType = ClassUtils.getUserClass(handlerType);
Set<Method> methods = HandlerMethodSelector.selectMethods(userType, new MethodFilter() {
public boolean matches(Method method) {
return getMappingForMethod(method, userType) != null;
}
});
for (Method method : methods) {
T mapping = getMappingForMethod(method, userType);
registerHandlerMethod(handler, method, mapping);
}
}

4.ok。registerHandlerMethod方法做了哪些东西?其实就是这个地方就是做了请求映射。源码中有两个变量做了记录,handlerMethods和urlMap。

handlerMethods Map格式,<key,value>分别记录了 <匹配条件,处理器> 自认为就是 <mappinginfo,controller>,例如<addStudent,StudentAction>,<deleteStudent,StedentAction>,  其实这边的mapping就是通过getMappingForMethod 拼接/student 和/addstudent获取到完整的对应到addstudent这个方法上的一个匹配条件。通过源码观看,可以发现

mapping 记录为 {[/student/addStudent],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]} --> 也指向了addStudent这个方法

@requestMaping(/student)

public class Student{

@requestmapping(/addStudent, method = Get)

public addStudent(){

}

}

urlMap 也是 Map格式, <key,value> 分别记录的是 <url,匹配条件> 可以认为是 <url,mappinginfo>  </addStudent,addStudent>,这个显而易见了,就是你addStudent方法上面的requestMapping中写的url路径。



0 0
原创粉丝点击