tomcat会读取web.xml,从里面获取servlet class得到DispatcherServlet,父类是HttpServlet,有doget,dopost,传入request,传出response。
tomcat在开始的时候会调用HttpServlet的init方法,子类重写这个方法。frameworkServlet继承HttpServlet,增加WebApplicationContext。
DispatcherServlet继承frameworkServlet,增加HandlerMapping和handlerAdapters。
最开始首先创建WebApplicationContext。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
finishBeanFactoryInitialization(beanFactory);
}
}
在obtainFreshBeanFactory的loadBeanDefinitions,会调用getDefaultConfigLocation,Namespace就是xml配置的servlet-name,读取的就是dispatcher-servlet.xml。
protected String getDefaultConfigLocation() {
if (getNamespace() != null) {
return DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX;
}
else {
return DEFAULT_CONFIG_LOCATION;
}
}
这里对beanfactory进行BeanDefinition注册。
else if(namespaceUri.equals("http://www.springframework.org/schema/context")&& ele.getLocalName().equals("component-scan")){
//找出需要搜索的包,并注册controller
NamespaceHandler namespaceHandler=this.namespaceHandlers.get(namespaceUri);
namespaceHandler.parse(ele,this.registry);
}
else if(namespaceUri.equals("http://www.springframework.org/schema/mvc") && ele.getLocalName().equals("annotation-driven")){
BeanDefinition handlerMappingDef = null;
try {
handlerMappingDef = new BeanDefinition(HANDLER_MAPPING_BEAN_NAME);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
this.registry.registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME , handlerMappingDef);
BeanDefinition handlerAdapterDef = null;
try {
handlerAdapterDef = new BeanDefinition(HANDLER_ADAPTER_BEAN_NAME);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
this.registry.registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME , handlerAdapterDef);
}
module不能循环依赖,怎么互相使用对方的类呢?
通过反射
NamespaceHandlerSupport这个类提供了基本的解析功能,由子类实现init方法来注册parser。
context:component-scan扫描对应的包,读取类信息,注册beandefinition
public SetdoScan(String... basePackages) { Set beanDefinitions = new linkedHashSet<>(); for (String basePackage : basePackages) { Set candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { String beanName = null; try { beanName = candidate.getBeanClass().getName(); } catch (ClassNotFoundException e) { e.printStackTrace(); } BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); beanDefinitions.add(definitionHolder); this.registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); } } return beanDefinitions; }
private Set递归扫描注解scanCandidateComponents(String basePackage) throws Exception { Set candidates = new linkedHashSet<>(); try { String packageSearchPath = PathMatchingResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + basePackage + '/' + this.resourcePattern; Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath); for (Resource resource : resources) { try { metadataReader metadataReader = new SimplemetadataReader(resource); if (isCandidateComponent(metadataReader)) { candidates.add(new BeanDefinition(metadataReader.getClassName())); } } catch (Throwable ex) { throw new Exception( "Failed to read candidate component class: " + resource, ex); } } }
使用深度优先搜索,扫描注解。如果包含@component,则把这个类注册到容器里。
public void visitEnd() {
super.visitEnd();
Class> annotationClass = this.annotationType;
if (annotationClass != null) {
Set visited = new linkedHashSet<>();
Annotation[] metaAnnotations = AnnotationUtils.getAnnotations(annotationClass);
if (!ObjectUtils.isEmpty(metaAnnotations)) {
for (Annotation metaAnnotation : metaAnnotations) {
recursivelyCollectmetaAnnotations(visited, metaAnnotation);
}
}
Set metaAnnotationTypeNames = new linkedHashSet<>(visited.size());
for (Annotation ann : visited) {
metaAnnotationTypeNames.add(ann.annotationType().getName());
}
this.metaAnnotationMap.put(annotationClass.getName(), metaAnnotationTypeNames);
}
}
private void recursivelyCollectmetaAnnotations(Set visited, Annotation annotation) {
Class extends Annotation> annotationType = annotation.annotationType();
if (visited.add(annotation)) {
try {
for (Annotation metametaAnnotation : annotationType.getAnnotations()) {
recursivelyCollectmetaAnnotations(visited, metametaAnnotation);
}
}
catch (Throwable ignored) {
}
}
}
mvc:annotation-driven
注册RequestMappingHandlerMapping和RequestMappingHandlerAdapter到容器里。
RequestMappingHandlerMappingRequestMappingHandlerMapping实现了InitializingBean接口,在创建bean的initialize时候,beanfactory会调用这个方法。
public void afterPropertiesSet() {
initHandlerMethods();
}
protected abstract boolean isHandler(Class> beanType);
protected void initHandlerMethods() {
String[] beanNames = obtainApplicationContext().getBeanNamesForType(Object.class);
for (String beanName : beanNames) {
Class> beanType = null;
try {
beanType = obtainApplicationContext().getType(beanName);
}
catch (Throwable ignored) {
}
if (beanType != null && isHandler(beanType)) {
detectHandlerMethods(beanName);
}
}
}
检查beanfactory里的所有bean,看看有没有注解。
protected boolean isHandler(Class> beanType) {
return beanType.isAnnotationPresent(Controller.class) || beanType.isAnnotationPresent(RequestMapping.class);
}
检查所有方法,看看有没有RequestMapping,有的话记录下path、方法、bean。
protected void detectHandlerMethods(final Object handler) {
Class> handlerType = (handler instanceof String ?
obtainApplicationContext().getType((String) handler) : handler.getClass());
if (handlerType != null) {
final Class> userType = handlerType;
Map methods = MethodIntrospector.selectMethods(userType,
method -> {
try {
return getMappingForMethod(method, userType);
}
catch (Throwable ex) {
throw new IllegalStateException("Invalid mapping on handler class [" +
userType.getName() + "]: " + method, ex);
}
});
for (Map.Entry entry : methods.entrySet()) {
Method invocableMethod = entry.getKey();
T mapping = entry.getValue();
registerHandlerMethod(obtainApplicationContext().getBean((String) handler), invocableMethod, mapping);
}
}
}
```java
private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
RequestMapping requestMapping = element.getAnnotation(RequestMapping.class);
if(requestMapping==null){
return null;
}
return createRequestMappingInfo(requestMapping);
}
protected RequestMappingInfo createRequestMappingInfo(
RequestMapping requestMapping) {
return new RequestMappingInfo(requestMapping.path());
}
protected RequestMappingInfo getMappingForMethod(Method method, Class> handlerType) {
RequestMappingInfo info = createRequestMappingInfo(method);
if (info != null) {
RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
if (typeInfo != null) {
info = typeInfo.combine(info);
}
}
return info;
}
```java
public RequestMappingInfo combine(RequestMappingInfo other) {
String paths = this.path+other.path;
return new RequestMappingInfo(paths);
}
RequestMappingHandlerAdapter
负责解析参数,把结果转换成json,初始化的时候注册这个adapter到容器里。
处理请求初始化负责把对应的handler注册到容器里,构建路由等。那么怎么处理请求的呢?其实就是根据request的uri进行路由,调用相应的方法,在把结果写进response。
主要是就是获取注解的参数,然后根据参数获取request里相应的参数。调用函数后,再写入json。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception{
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
ha.handle(processedRequest, response, mappedHandler.getHandler());
}
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
String lookupPath = request.getServletPath();
T mapping = this.mappingRegistry.getMappingsByUrl(lookupPath);
HandlerMethod handlerMethod = this.mappingRegistry.getMappings().get(mapping);
return handlerMethod;
}
protected void invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception{
Object []args=getMethodArgumentValues(request,handlerMethod);
Object returnValue = handlerMethod.getMethod().invoke(handlerMethod.getBean(),args);
this.requestResponseBodyMethodProcessor.handleReturnValue(returnValue,response);
}
public void handleReturnValue(Object returnValue, HttpServletResponse response){
try {
response.setHeader("Content-Type", "application/json");
this.gson.toJson(returnValue, response.getWriter());
} catch (IOException e) {
e.printStackTrace();
}
}



