从Jetty启动流程可以看到,启动上下文之后,紧接着就开始初始化servlet,调用init方法
private synchronized void initServlet()
throws ServletException
{
...
//调用Servlet的init方法
_servlet.init(_config);
...
}
从web.xml文件中可以看到,这个servlet就是DispatcherServlet,对应的init方法在父类GenericServlet中
public void init(ServletConfig config) throws ServletException {
//这里servletconfig就被传下来
this.config = config;
//执行子类的init方法
this.init();
}
对应在 HttpServletBean中
public final void init() throws ServletException {
...
initServletBean();
}
在FrameworkServlet中实现对应的spring的servlet的初始化
protected final void initServletBean() throws ServletException {
…
this.webApplicationContext = initWebApplicationContext();
…
}
对应的初始化web容器,首先也会去查询是否已经初始化过了
protected WebApplicationContext initWebApplicationContext() {
//获取根webapplicationcontext,这就是在IOC容器初始化的时候塞入的值,如果IoC容器已经初始化完成,那么这里的值肯定不是null
WebApplicationContext rootContext =
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext wac = null;
if (this.webApplicationContext != null) {
wac = this.webApplicationContext;
if (wac instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
if (!cwac.isActive()) {
//如果没有执行过webcontextapplication的refresh,那么再执行一次
if (cwac.getParent() == null) {
cwac.setParent(rootContext);
}
//这个过程就类似IOC的启动了
configureAndRefreshWebApplicationContext(cwac);
}
}
}
...
if (!this.refreshEventReceived) {
//没有执行过refresh则执行一次
onRefresh(wac);
}
….
return wac;
}
对于这个时间点的DispatcherServlet启动来说,核心在于 onRefresh
,它会去初始化各种resolver
protected void onRefresh(ApplicationContext context) {
…
initMultipartResolver(context);
...
initHandlerMappings(context);
...
initViewResolvers(context);
…
}
MultipartResolver
它会从容器中读取是否包含 bean ‘multipartResolver’
public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver”;
...
private void initMultipartResolver(ApplicationContext context) {
...
this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
...
}
MultipartResolver是用来解决文件上传问题
HandlerMappings
默认自己去扫描所有HandlerMapping类型的
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;
if (this.detectAllHandlerMappings) {
//默认这里执行主动探测,这里的实现其实就是从BeanFactory中获取所有已经注册了的,且类型是HandlerMapping的类的名字,然后再从BeanFactory中获取所有这个名字的bean作为返回
Map<String, HandlerMapping> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList<>(matchingBeans.values());
AnnotationAwareOrderComparator.sort(this.handlerMappings);
}
}
...
if (this.handlerMappings == null) {
//没有handlerMapping,则使用默认的。
this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
if (logger.isTraceEnabled()) {
logger.trace("No HandlerMappings declared for servlet '" + getServletName() +
"': using default strategies from DispatcherServlet.properties");
}
}
}
在没有配置的情况下,处理映射的类配置在spring自带的文件DispatcherServlet.properties
中,默认handlerMapping的类为
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\ org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
HandlerMapping负责定义请求和处理请求的对象之间的映射
以RequestMappingHandlerMapping
为例。当获取到对应的名字后
protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
String key = strategyInterface.getName();
//获取默认的配置
String value = defaultStrategies.getProperty(key);
….
//通过反射构建class对象
Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());
//从beanFactory中获取对象,其实就是调用createBean方法
Object strategy = createDefaultStrategy(context, clazz);
strategies.add((T) strategy);
}
….
}
对于beanFactory来说,创建一个bean或经历它的完整生命周期,经过多层查找,可以看到如下代码
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
...
instanceWrapper = createBeanInstance(beanName, mbd, args);
...
final Object bean = instanceWrapper.getWrappedInstance();
...
Object exposedObject = bean;
...
exposedObject = initializeBean(beanName, exposedObject, mbd);
...
}
执行一些列的生命名周期方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
...
//执行各种aware方法
invokeAwareMethods(beanName, bean);
…
//执行初始化之前的BeanPostProcessor相关方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
…
//执行初始化bean方法
invokeInitMethods(beanName, wrappedBean, mbd);
…
//执行初始化之后的BeanPostProcessor相关方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
...
}
-aware 方法
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
初始化bean又包含了相关生命周期要执行的逻辑
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
…
//执行afterPropertiesSet
((InitializingBean) bean).afterPropertiesSet();
...
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
//执行自己的initMethod方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
对于 RequestMappingHandlerMapping 继承了接口ApplicationContextAware
和 InitializingBean
,都属于bean生命周期中的一环。
ApplicationContextAware
RequestMappingHandlerMapping的父类自己持有一个applicationContext的引用
public final void setApplicationContext(@Nullable ApplicationContext context) throws BeansException {
...
else if (this.applicationContext == null) {
...
this.applicationContext = context;
this.messageSourceAccessor = new MessageSourceAccessor(context);
initApplicationContext(context);
}
...
}
从父类开始往下去执行对应的方法
protected void initApplicationContext() throws BeansException {
…
//探测所有的interceptor,即找到所有类MappedInterceptor【这对应 mvc-interceptor标签】和实现了接口HandlerInterceptor的拦截器
detectMappedInterceptors(this.adaptedInterceptors);
//初始化interceptor
initInterceptors();
}
InitializingBean
public void afterPropertiesSet() {
…
//getCandidateBeanNames默认就是获取所有的bean
for (String beanName : getCandidateBeanNames()) {
//判断 bean 的名字是否是 “scopedTarget.” 字符串开头
if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
processCandidateBean(beanName);
}
}
…
}
查到bean后,开始识别是否是用来处理请求的
protected void processCandidateBean(String beanName) {
Class<?> beanType = null;
...
beanType = obtainApplicationContext().getType(beanName);
…
//isHandler即判断这个beanType是否包含注解 Controller 或者 RequestMapping
if (beanType != null && isHandler(beanType)) {
//找到这个注解bean的所有方法,构建映射关系
detectHandlerMethods(beanName);
}
}
protected boolean isHandler(Class<?> beanType) {
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
探测handler的方法分成两个主要部分
1、 找到这个bean的所有的方法
2、 将方法注册
protected void detectHandlerMethods(Object handler) {
…
//找到这个bean的方法
Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
(MethodIntrospector.MetadataLookup<T>) method -> {
try {
//找到方法对应的RequestMapping注解,将它的path等参数封装成RequestMappingInfo返回
return getMappingForMethod(method, userType);
}
catch (Throwable ex) {
throw new IllegalStateException("Invalid mapping on handler class [" +
userType.getName() + "]: " + method, ex);
}
});
...
methods.forEach((method, mapping) -> {
Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
//注册handler,在内部创建HandlerMethod,在urlLookup中存储 url和mapping的关系,而mapping和HandlerMethod则存储在mappingLookup中
registerHandlerMethod(handler, invocableMethod, mapping);
});
...
}
initViewResolvers
同handlerMapping,默认类为
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
根据view的名字来找到对应的View。View则负责来渲染内容
spring 处理请求到来
从Jetty请求过程可以看到,执行请求对应着的是servlet的service方法,对应spring来说,他就是DispatcherServlet
protected void doService(HttpServletRequest request, HttpServletResponse response) {
…
//请求总设置applicationContext
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
…
//进行请求分发
doDispatch(request, response);
…
}
doDispatch负责把一次请求分配给对应的handler来处理
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
...
ModelAndView mv = null;
...
//如果请求存在分段文件,则转换成Multipart,比如MultipartHttpServletRequest
processedRequest = checkMultipart(request);
…
//获取对应请求的handler
mappedHandler = getHandler(processedRequest);
…
//返回这个hander对应的适配器,比如对于HandlerMethod子类返回的就是AbstractHandlerMethodAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
…
//调用interceptor的preHandle方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
…
//执行处理逻辑
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
…
//掉interceptor的postHandle方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
….
//处理结果
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
...
}
getHandler详细处理如下
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//内部根据请求的路径执行lookupHandlerMethod(lookupPath, request),而它就会从 urlLookup.get(urlPath)中查到对应的mapping,再查到HanlerMethod
Object handler = getHandlerInternal(request);
…
//匹配路径的拦截器全都加到handler链路里面来
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
...
return executionChain;
}
handler核心逻辑如下
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
...
//将handlerMethod进行包装,以便后续通过反射执行
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
。。。
//创建ModelAndView的容器
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
…
//通过反射执行
invocableMethod.invokeAndHandle(webRequest, mavContainer);
…
//获取ModeAndView,从内部可以看到,它会自行创建一个ModelAndView对象
return getModelAndView(mavContainer, modelFactory, webRequest);
...
}
获得handler的结果之后,调用processDispatchResult,核心就是进行render
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {
...
render(mv, request, response);
...
}
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
….
View view;
//获取视图的名字
String viewName = mv.getViewName();
//根据名字获取对应的视图
view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
…
//执行渲染
view.render(mv.getModelInternal(), request, response);
...
}
执行render方法来源与所有render的父类AbstractView的render方法
@Overridepublic void render(@Nullable Map<String, ?> model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
….
Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);
prepareResponse(request, response);
//真正执行渲染
renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);
}
比如返回的是JSON对象,那么实际情况如下
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
Object value = this.filterModel(model);
//值封装成json
String text = JSON.toJSONString(value, this.serializerFeatures);
byte[] bytes = text.getBytes(this.charset);
Object stream = this.updateContentLength?this.createTemporaryOutputStream():response.getOutputStream();
//结果写入outpuststream
((OutputStream)stream).write(bytes);
if(this.updateContentLength) {
//返回
this.writeToResponse(response, (ByteArrayOutputStream)stream);
}
}
对于Freemarker来说,就是执行FreemarkerView.renderMergedTemplateModel方法,内部执行doRender
protected void doRender(Map<String, Object> model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
exposeModelAsRequestAttributes(model, request);
SimpleHash fmModel = buildTemplateModel(model, request, response);
Locale locale = RequestContextUtils.getLocale(request);
//这里就是调用Freemarker的template来处理对应的数据填充等等 template.process(model, response.getWriter());
processTemplate(getTemplate(locale), fmModel, response);
}
至此一次请求结束