`

DispatcherServlet

 
阅读更多

在第一次访问项目时,DispatcherServlet作为一个servlet,首先需要init();然后才能处理请求。

 

一、初始化:

       由容器调用底层的servet接口的init()方法,DispatcherServlet->FrameworkServlet->HttpServletBean->HttpServlet,其init()方法最终调用了DispatcherServlet的protected void onRefresh(ApplicationContext context) {initStrategies(context);}(如下),该方法初始化了基本上所有需要的内容,其中,context参数为WebApplicationContext,为web容器(jetty、tomcat)持有,传递给HttpServlet基础虚拟类

 

      protected void initStrategies(ApplicationContext context) {
		initMultipartResolver(context);//文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析;
		initLocaleResolver(context);//本地化解析
		initThemeResolver(context);
		initHandlerMappings(context);//通过HandlerMapping,将请求映射到处理器
		initHandlerAdapters(context);//通过HandlerAdapter支持多种类型的处理器
		initHandlerExceptionResolvers(context);//如果执行过程中遇到异常将交给HandlerExceptionResolver来解析
		initRequestToViewNameTranslator(context);/直接解析请求到视图名
		initViewResolvers(context);//通过ViewResolver解析逻辑视图名到具体视图实现
		initFlashMapManager(context);
	}

 1、initMultipartResolver,initLocaleResolver,initThemeResolver,initRequestToViewNameTranslator,initFlashMapManager 初始化方式相同,都为单个resolver,比如:

 

private void initLocaleResolver(ApplicationContext context) {
		try {
			this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Using LocaleResolver [" + this.localeResolver + "]");
			}
		}
		catch (NoSuchBeanDefinitionException ex) {
			// We need to use the default.
			this.localeResolver = getDefaultStrategy(context, LocaleResolver.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate LocaleResolver with name '" + LOCALE_RESOLVER_BEAN_NAME +
						"': using default [" + this.localeResolver + "]");
			}
		}
	}

 2、initHandlerMappings,initHandlerAdapters,initHandlerExceptionResolvers,initViewResolvers 初始化方式相同,为多个resolver,比如:

 

private void initHandlerMappings(ApplicationContext context) {
		this.handlerMappings = null;
		if (this.detectAllHandlerMappings) {
			// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
			Map<String, HandlerMapping> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());
				// We keep HandlerMappings in sorted order.
				AnnotationAwareOrderComparator.sort(this.handlerMappings);
			}
		}
		else {
			try {
				HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
				this.handlerMappings = Collections.singletonList(hm);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore, we'll add a default HandlerMapping later.
			}
		}

		// Ensure we have at least one HandlerMapping, by registering
		// a default HandlerMapping if no other mappings are found.
		if (this.handlerMappings == null) {
			this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
			if (logger.isDebugEnabled()) {
				logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default");
			}
		}
	}

 3、而BeanFactoryUtils.beansOfTypeIncludingAncestors()实现如下:

 

 

public static <T> Map<String, T> beansOfTypeIncludingAncestors(
			ListableBeanFactory lbf, Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
			throws BeansException {
		Assert.notNull(lbf, "ListableBeanFactory must not be null");
		Map<String, T> result = new LinkedHashMap<String, T>(4);
		result.putAll(lbf.getBeansOfType(type, includeNonSingletons, allowEagerInit));
		if (lbf instanceof HierarchicalBeanFactory) {
			HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
			if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
				Map<String, T> parentResult = beansOfTypeIncludingAncestors(
						(ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
				for (Map.Entry<String, T> entry : parentResult.entrySet()) {
					String beanName = entry.getKey();
					if (!result.containsKey(beanName) && !hbf.containsLocalBean(beanName)) {
						result.put(beanName, entry.getValue());
					}
				}
			}
		}
		return result;
	}

 而lbf.getBeansOfType()的默认DefaultListableBeanFactory实现如下(要记得ApplicationContext继承了ListableBeanFactory):

public <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
			throws BeansException {
		String[] beanNames = getBeanNamesForType(type, includeNonSingletons, allowEagerInit);//获取该类以及子类的所有bean
		Map<String, T> result = new LinkedHashMap<String, T>(beanNames.length);
		for (String beanName : beanNames) {
			try {
				result.put(beanName, getBean(beanName, type));
			}
			catch (BeanCreationException ex) {
				Throwable rootCause = ex.getMostSpecificCause();
				if (rootCause instanceof BeanCurrentlyInCreationException) {
					BeanCreationException bce = (BeanCreationException) rootCause;
					if (isCurrentlyInCreation(bce.getBeanName())) {
						if (this.logger.isDebugEnabled()) {
							this.logger.debug("Ignoring match to currently created bean '" + beanName + "': " +
									ex.getMessage());
						}
						onSuppressedException(ex);
						// Ignore: indicates a circular reference when autowiring constructors.
						// We want to find matches other than the currently created bean itself.
						continue;
					}
				}
				throw ex;
			}
		}
		return result;
	}

 

 

 

二、响应请求:

待续。。。

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics