一、AnnotationDrivenBeanDefinitionParser
通過注解的方式開發(fā)Spring MVC,要在***-servlet.xml
中加入<mvc:annotation-driven/>
標(biāo)簽。
先找到它的解析類。所有自定義命名空間(像mvc,context等)標(biāo)簽解析都是由BeanDefinitionParser
接口的子類來完成的默刚。
<mvc:annotation-driven/>
標(biāo)簽對應(yīng)的解析類是`org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser·。這個類主要是向工廠中注冊了
- RequestMappingHandlerMapping
- BeanNameUrlHandlerMapping
- RequestMappingHandlerAdapter
- HttpRequestHandlerAdapter
- SimpleControllerHandlerAdapter
- ExceptionHandlerExceptionResolver
- ResponseStatusExceptionResolver
- DefaultHandlerExceptionResolver
前兩個是HandlerMapping
接口的實(shí)現(xiàn)類逃魄,用來處理請求映射的羡棵。其中第一個是處理@RequestMapping
注解的。第二個會將controller類的名字映射為請求url嗅钻。
中間三個是用來處理請求的皂冰。確定調(diào)用哪個controller的哪個方法來處理當(dāng)前請求。第一個處理@Controller
注解的處理器养篓,支持自定義方法參數(shù)和返回值秃流。第二個是處理繼承HttpRequestHandler的處理器。第三個處理繼承自Controller接口的處理器柳弄。
后面三個是用來處理異常的解析器舶胀。
二、實(shí)現(xiàn)
public BeanDefinition parse(Element element, ParserContext parserContext) {
Object source = parserContext.extractSource(element);
CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
parserContext.pushContainingComponent(compDefinition);
RuntimeBeanReference contentNegotiationManager = getContentNegotiationManager(element, source, parserContext);
//第一個在這 RequestMappingHandlerMapping
RootBeanDefinition handlerMappingDef = new RootBeanDefinition(RequestMappingHandlerMapping.class);
handlerMappingDef.setSource(source);
handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
handlerMappingDef.getPropertyValues().add("order", 0);
handlerMappingDef.getPropertyValues().add("removeSemicolonContent", false);
handlerMappingDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
String methodMappingName = parserContext.getReaderContext().registerWithGeneratedName(handlerMappingDef);
//第二個在這 RequestMappingHandlerAdapter
RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(RequestMappingHandlerAdapter.class);
handlerAdapterDef.setSource(source);
handlerAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
handlerAdapterDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
handlerAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
handlerAdapterDef.getPropertyValues().add("messageConverters", messageConverters);
if (element.hasAttribute("ignoreDefaultModelOnRedirect")) {
Boolean ignoreDefaultModel = Boolean.valueOf(element.getAttribute("ignoreDefaultModelOnRedirect"));
handlerAdapterDef.getPropertyValues().add("ignoreDefaultModelOnRedirect", ignoreDefaultModel);
}
if (argumentResolvers != null) {
handlerAdapterDef.getPropertyValues().add("customArgumentResolvers", argumentResolvers);
}
if (returnValueHandlers != null) {
handlerAdapterDef.getPropertyValues().add("customReturnValueHandlers", returnValueHandlers);
}
if (asyncTimeout != null) {
handlerAdapterDef.getPropertyValues().add("asyncRequestTimeout", asyncTimeout);
}
if (asyncExecutor != null) {
handlerAdapterDef.getPropertyValues().add("taskExecutor", asyncExecutor);
}
handlerAdapterDef.getPropertyValues().add("callableInterceptors", callableInterceptors);
handlerAdapterDef.getPropertyValues().add("deferredResultInterceptors", deferredResultInterceptors);
String handlerAdapterName = parserContext.getReaderContext().registerWithGeneratedName(handlerAdapterDef);
//異常處理解析器
RootBeanDefinition exceptionHandlerExceptionResolver = new RootBeanDefinition(ExceptionHandlerExceptionResolver.class);
exceptionHandlerExceptionResolver.setSource(source);
exceptionHandlerExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
exceptionHandlerExceptionResolver.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
exceptionHandlerExceptionResolver.getPropertyValues().add("messageConverters", messageConverters);
exceptionHandlerExceptionResolver.getPropertyValues().add("order", 0);
String methodExceptionResolverName =
parserContext.getReaderContext().registerWithGeneratedName(exceptionHandlerExceptionResolver);
//異常處理解析器
RootBeanDefinition responseStatusExceptionResolver = new RootBeanDefinition(ResponseStatusExceptionResolver.class);
responseStatusExceptionResolver.setSource(source);
responseStatusExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
responseStatusExceptionResolver.getPropertyValues().add("order", 1);
String responseStatusExceptionResolverName =
parserContext.getReaderContext().registerWithGeneratedName(responseStatusExceptionResolver);
//異常處理解析器
RootBeanDefinition defaultExceptionResolver = new RootBeanDefinition(DefaultHandlerExceptionResolver.class);
defaultExceptionResolver.setSource(source);
defaultExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
defaultExceptionResolver.getPropertyValues().add("order", 2);
String defaultExceptionResolverName =
parserContext.getReaderContext().registerWithGeneratedName(defaultExceptionResolver);
parserContext.registerComponent(new BeanComponentDefinition(handlerMappingDef, methodMappingName));
parserContext.registerComponent(new BeanComponentDefinition(handlerAdapterDef, handlerAdapterName));
parserContext.registerComponent(new BeanComponentDefinition(exceptionHandlerExceptionResolver, methodExceptionResolverName));
parserContext.registerComponent(new BeanComponentDefinition(responseStatusExceptionResolver, responseStatusExceptionResolverName));
parserContext.registerComponent(new BeanComponentDefinition(defaultExceptionResolver, defaultExceptionResolverName));
parserContext.registerComponent(new BeanComponentDefinition(mappedCsInterceptorDef, mappedInterceptorName));
//這里注冊了BeanNameUrlHandlerMapping碧注,SimpleControllerHandlerAdapter等
// Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off"
MvcNamespaceUtils.registerDefaultComponents(parserContext, source);
parserContext.popAndRegisterContainingComponent();
return null;
}
//在這啊嚣伐。
public static void registerDefaultComponents(ParserContext parserContext, Object source) {
registerBeanNameUrlHandlerMapping(parserContext, source);
registerHttpRequestHandlerAdapter(parserContext, source);
registerSimpleControllerHandlerAdapter(parserContext, source);
}
三、總結(jié)
RequestMappingHandlerMapping和RequestMappingHandlerAdapter
:第一個是HandlerMapping
的實(shí)現(xiàn)類萍丐,它會處理@RequestMapping
注解轩端,并將其注冊到請求映射表中。
第二個是HandlerAdapter
的實(shí)現(xiàn)類逝变,它是處理請求的適配器基茵,說白了奋构,就是確定調(diào)用哪個類的哪個方法,并且構(gòu)造方法參數(shù)拱层,返回值弥臼。
<context:component-scan/>
標(biāo)簽是告訴Spring掃描指定包下的類,并注冊被@Component
根灯,@Controller
径缅,@Service
,@Repository
等注解標(biāo)記的組件烙肺。
<mvc:annotation-scan/>
是告知Spring啟用注解驅(qū)動纳猪。然后Spring會自動為我們注冊上面說到的幾個Bean到工廠中,來處理我們的請求茬高。