springmvc整合springboot执行流程---源码分析

springmvc整合springboot执行流程---源码分析,第1张

springmvc整合springboot执行流程---源码分析

        本文介绍springmvc被springboot整合之后,web容器注册spring容器,初始化DispatcherServlet,controller里面的方法注册,访问过程。

首先从springboot-autoconfigure包下面的meta-INF/spring-factories里面找到WebMvcAutoConfiguration这个自动配置类,在209行会看到RequestMappingHandlerMapping这个类被创建成bean,这个类有个afterPropertiesSet()方法,在spring容器初始化就会调用这个方法,这个方法用来处理所有标记有@controller的注解的类,并找出所有标记@RequestMapping注解的方法,存到HandlerMethod类里。等第一次访问时就走DispathServlet的init初始化流程

 

注册类 

部分代码

在spring-factories文件里会找到DispatcherServletAutoConfiguration和WebMvcAutoConfiguration,其他的类那你也可以自己打开看看,断点调试。

spring.factories文件中部分代码

org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,

进入DispatcherServletAutoConfiguration类打断点可以看到图,这里会注册一个dispatchServlet,拦截路径是   /   。后面访问的时候会进入初始化方法init()。

 断点进入AbstractHandlerMethodMapping类

@Override
	public void afterPropertiesSet() {
		initHandlerMethods();
	}

	
	protected void initHandlerMethods() {
    // 获取spring容器中所有的bean,进行处理
		for (String beanName : getCandidateBeanNames()) {
			if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
        //处理bean的方法,会进行过滤
				processCandidateBean(beanName);
			}
		}
// 空方法
		handlerMethodsInitialized(getHandlerMethods());
	}

看截图

 这里会进入发现处理的方法。看判断的isHandler(beanType)这个方法,这里进行过滤

@Override
	protected boolean isHandler(Class beanType) {
		return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
				AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
	}
protected void detectHandlerMethods(Object handler) {
		Class handlerType = (handler instanceof String ?
				obtainApplicationContext().getType((String) handler) : handler.getClass());

		if (handlerType != null) {
			Class userType = ClassUtils.getUserClass(handlerType);
			Map methods = MethodIntrospector.selectMethods(userType,
					(MethodIntrospector.metadataLookup) method -> {
						try {
                        //找到所有的方法,可以进入这里看看
							return getMappingForMethod(method, userType);
						}
						catch (Throwable ex) {
							throw new IllegalStateException("Invalid mapping on handler class [" +
									userType.getName() + "]: " + method, ex);
						}
					});
			if (logger.isTraceEnabled()) {
				logger.trace(formatMappings(userType, methods));
			}
			else if (mappingsLogger.isDebugEnabled()) {
				mappingsLogger.debug(formatMappings(userType, methods));
			}
			methods.forEach((method, mapping) -> {
				Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
        // 注册方法到map中
				registerHandlerMethod(handler, invocableMethod, mapping);
			});
		}
	}

注册方法AbstractHandlerMethodMapping这个类中

protected void registerHandlerMethod(Object handler, Method method, T mapping) {
		this.mappingRegistry.register(mapping, handler, method);
	}

注册

public void register(T mapping, Object handler, Method method) {
			this.readWriteLock.writeLock().lock();
			try {
// 创建方法类
				HandlerMethod handlerMethod = createHandlerMethod(handler, method);
//校验是否已经存在
				validateMethodMapping(handlerMethod, mapping);

				Set directPaths = AbstractHandlerMethodMapping.this.getDirectPaths(mapping);
				for (String path : directPaths) {
					this.pathLookup.add(path, mapping);
				}

				String name = null;
				if (getNamingStrategy() != null) {
					name = getNamingStrategy().getName(handlerMethod, mapping);
					addMappingName(name, handlerMethod);
				}

				CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);
				if (corsConfig != null) {
					corsConfig.validateAllowCredentials();
					this.corsLookup.put(handlerMethod, corsConfig);
				}
// 注册到map中,以后拿处理器映射器从这里找
				this.registry.put(mapping,
						new MappingRegistration<>(mapping, handlerMethod, directPaths, name, corsConfig != null));
			}
			finally {
				this.readWriteLock.writeLock().unlock();
			}
		}
页面访问任意路径:

后续补齐

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5686868.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-17
下一篇2022-12-17

发表评论

登录后才能评论

评论列表(0条)

    保存