本文承接前文Spring源碼情操陶冶-DefaultBeanDefinitionDocumentReader#parseBeanDefinitions,特開闢出一塊新地來啃啃這塊有意思的骨頭html
咱們經常使用的可分爲spring/springmvc兩類java
spring經常使用的節點類型spring
- context類型
context-component-scan
-掃描包內的全部class類並註冊爲beanDefinition到spring上下文context-property-placeholder
-加載外部的資源供spring調用,經常使用${}
來使用外部文件的屬性context-annotation-config
-自動對註冊的beanDefinition進行註解處理,經常使用context-component-scan
來代替
- aop類型
aop-config
-AOP模式使用配置- task類型
task-annotation-driven
-任務處理配置task-executor
-任務線程池配置task-scheduler
、task-scheduled-tasks
-預先任務處理配置
springmvc經常使用的節點類型跨域
mvc-annotation-driven
-mvc註解式配置,多與context-component-scan
搭配使用mvc-interceptors
-mvc攔截器配置mvc-resources
-mvc靜態資源訪問配置mvc-freemarker-configurer
/mvc-velocity-configurer
/mvc-groovy-configurer
-視圖渲染器配置mvc-cors
-跨域資源訪問配置
NamespaceHandlerSupport
是NamespaceHandler
接口的直接實現類,後續的自定義節點的解析類都是繼承此類來進行擴展的。這裏咱們只關注NamespaceHandler
的兩個實現方法init
和parse
mvc
init()
初始化方法,抽象類中並無對其進行復寫,主要由繼承的子類去複寫,目的是初始化自定義節點的相關解析類並保存至NamespaceHandlerSupport#parsers
map集合中cors
Spring源碼情操陶冶-DefaultBeanDefinitionDocumentReader#parseBeanDefinitions
章節中咱們提到其會調用NamespaceHandler
的通用方法parse
也就是此方法來進行相應節點的解析,代碼以下@Override public BeanDefinition parse(Element element, ParserContext parserContext) { //找到相應的解析器並進行解析 return findParserForElement(element, parserContext).parse(element, parserContext); }
順藤摸瓜看下NamespaceHandlerSupport#findParserForElement
方法ide
private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) { //通常都是相似context-component-scan、mvc-resources這樣的節點名 String localName = parserContext.getDelegate().getLocalName(element); //此處顯而易見可察覺經過parsers這個map集合獲取相應的解析器 BeanDefinitionParser parser = this.parsers.get(localName); if (parser == null) { parserContext.getReaderContext().fatal( "Cannot locate BeanDefinitionParser for element [" + localName + "]", element); } return parser; }
由此得出咱們能夠稍微密切關注下子類對init()
方法的複寫,即可得出相關的自定義節點對應的BeanDefinitionParser
解析器this
這裏只分析ContextNamespaceHandler-spring context空間處理類
、MvcNamespaceHandler-springmvc空間處理類
spa
先瞧瞧代碼,內部只有一個方法且也是複寫方法init()
線程
@Override public void init() { registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser()); registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser()); registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser()); registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser()); registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser()); registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser()); registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser()); registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser()); }
挑選幾個重要的解析器來分析
瞧瞧代碼
@Override public void init() { registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser()); registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser()); registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser()); registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser()); registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser()); registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser()); registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser()); registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser()); registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser()); registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser()); registerBeanDefinitionParser("velocity-configurer", new VelocityConfigurerBeanDefinitionParser()); registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser()); registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser()); registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser()); }
挑選重要的幾個解析器來分析
簡單的瞅下代碼
@Override public void init() { // In 2.0 XSD as well as in 2.1 XSD. registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser()); registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser()); registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator()); // Only in 2.0 XSD: moved to context namespace as of 2.1 registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser()); }
此處咱們就簡單的分析aop-config
節點對應的解析器>>>Spring源碼情操陶冶-AOP之ConfigBeanDefinitionParser解析器
task:executor>>>Spring源碼情操陶冶#task:executor解析器
task:scheduled-tasks、task:scheduler>>>Spring源碼情操陶冶#task:scheduled-tasks解析器
經過分析spring與springmvc經常使用的自定義標籤解析器,但願能幫助博主以及讀者更好的瞭解spring與springmvc的工做原理,方便在分析問題時更加駕輕就熟