springmvc @EnableWebMvc注解驱动学习,DispatcherServlet源码简单的分析

@EnableWebMvc  注解注入【DelegatingWebMvcConfiguration.class】类,把RequestMappingHandlerAdapter,RequestMappingHandlerMapping等自动加载到spring容器中。不需要再xml文件中配置映射。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}

使用 @EnableWebMvc 注解下面图的内容就不需要在xml配置。

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

 

需要在实现类中配置上面xml内容。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@Configuration
@EnableWebMvc
public class WebMvcConfig {

    @Bean
    public ViewResolver viewResolver(){
        InternalResourceViewResolver resourceViewResolver = new InternalResourceViewResolver();

        resourceViewResolver.setViewClass(JstlView.class);
        resourceViewResolver.setPrefix("/WEB-INF/jsp/");
        resourceViewResolver.setSuffix(".jsp");
        
        return resourceViewResolver;

    }


}

 

下面是DEBUG实现DispatcherServlet源码分析图片:

1.首先会进入 doService()方法。

2. 然后再 doService() 方法中调用doDispatch()方法。

 

3.在doDispatch()方法中,调用getHandler() 方法。可以看到 【RequestMappingHandlerMapping】类被加载进来了。

4. 然后再向下执行getHandlerInternal(request);方法,getHandlerInternal()方法中执行addMatchingMappings()遍历所有映射路径,返回请求的类名字。

5. 请求的地址被返回到doDispatch()方法。

7.然后进入getHandlerAdapter()方法,【RequestMappingHanderAdater】类也被加载进来了。然后找到对应的适配器。

8.在handle()向下执行就进入Controller方法,然后返回对应地址。

9. 下面就会进去视图全名称,然后调用对应的视图。

 

然后就会找到对应的视图返回。

 

看完之后有很多疑问。

比如:在源码中 handlerAdapters的值在哪设定的?

initHandlerAdapters()中方法中加载。initHandlerAdapters()中方法handlerAdapters 赋值是通过spring上下文进行加载。 handlerMappings的值也同样在initHandlerMappings方法中加载。

	private void initHandlerAdapters(ApplicationContext context) {
		this.handlerAdapters = null;

		if (this.detectAllHandlerAdapters) {
			// Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.
			Map<String, HandlerAdapter> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.handlerAdapters = new ArrayList<>(matchingBeans.values());
				// We keep HandlerAdapters in sorted order.
				AnnotationAwareOrderComparator.sort(this.handlerAdapters);
			}
		}
		else {
			try {
				HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
				this.handlerAdapters = Collections.singletonList(ha);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore, we'll add a default HandlerAdapter later.
			}
		}

		// Ensure we have at least some HandlerAdapters, by registering
		// default HandlerAdapters if no other adapters are found.
		if (this.handlerAdapters == null) {
			this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
			if (logger.isDebugEnabled()) {
				logger.debug("No HandlerAdapters found in servlet '" + getServletName() + "': using default");
			}
		}
	}

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值