Spring中的NamespaceHandler與BeanDefinitionParser詳解
1.前文
由Spring啟動過程之-obtainFreshBeanFactory()
可以看到NamespaceHandler、BeanDefinitionParser為解析配置文件中的Element起重要作用。
那么它本身是如何被加載的呢?
2.NamespaceHandler之ContextNamespaceHandler
常見的NamespaceHandler實例:ContextNamespaceHandler
很明顯能看出有常用的 context:annotation-config/、<context:component-scan base-package=“xx”/>、context:property-placeholder/對應(yīng)的解析類。
3.BeanDefinitionParser的作用
解析相關(guān)節(jié)點,并注冊BeanDefinition。
3.1 PropertyPlaceholderBeanDefinitionParser
大致流程為解析<context:property-placeholder location="classpath:module.properties" />節(jié)點,包裝PropertySourcesPlaceholderConfigurer為BeanDefinition,將里面的屬性裝配到BeanDefinition中,并注冊到BeanDefinitionMap。
PropertyPlaceholderBeanDefinitionParser#parse: AbstractBeanDefinitionParser-> parseInternal-> BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();//創(chuàng)建BeanDefinition ... builder.getRawBeanDefinition().setBeanClass(PropertySourcesPlaceholderConfigurer.class); ... doParse(element, parserContext, builder)-> super.doParse(element, parserContext, builder);//解析公共屬性:location,fileEncoding等 ....//做特殊屬性的解析 return builder.getBeanDefinition(); //統(tǒng)一注冊 registerBeanDefinition(holder, parserContext.getRegistry());
3.2 ComponentScanBeanDefinitionParser
解析節(jié)點<context:component-scan base-package="com.gkwind"/>本身。并根據(jù)其配置,做特殊的class掃描,將符合配置的class,如被@Component標記過的類 包裝成BeanDefinition,注入到BeanDefinitionMap中。 注意這里做的工作是根據(jù)配置,掃描加載了配置對應(yīng)的多個類
ComponentScanBeanDefinitionParser#parse流程
NamespaceHandler 加載過程
跟蹤源碼, 可以發(fā)現(xiàn)解析非自定義命名空間parseCustomElement時會調(diào)用DefaultNamespaceHandlerResolver#resolve,然后resolve得到的所有NamespaceHandler。之后得到命名空間對應(yīng)的NamespaceHandler 再NamespaceHandler#init初始化相關(guān)的parser。
getHandlerMappings以SPI的方式得到所有spring.handlers
NamespaceHandler 加載流程
作用:可實現(xiàn)自定義標簽
知道了NamespaceHandler與BeanDefinitionParser作用后, 我們可以自定義schema,然后在spring的xml中自定義命名空間thewindkee標簽<thewindkeetag>,再實現(xiàn)thewindkee對應(yīng)的NamespaceHandler與<thewindkeetag>的BeanDefinitionParser,最后將NamespaceHandler配置到META-INF/spring.handlers。
大致Java代碼:
class TheWindKeeNamespaceHandler extends NamespaceHandlerSupport { public void init(){ registerBeanDefinitionParser("thewindkeetag", new TheWindKeeTagBeanDefinitionParser()); } } class TheWindKeeTagBeanDefinitionParser extends AbstractBeanDefinitionParser{ public final BeanDefinition parse(Element element, ParserContext parserContext) { //解析element .... //注冊BeanDefinition registerBeanDefinition(holder, parserContext.getRegistry()); } }
到此這篇關(guān)于Spring中的NamespaceHandler與BeanDefinitionParser詳解的文章就介紹到這了,更多相關(guān)NamespaceHandler與BeanDefinitionParser內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于Springboot打成JAR包后讀取外部配置文件的問題
這篇文章主要介紹了關(guān)于Springboot打成JAR包后讀取外部配置文件的問題,本文給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11Java中轉(zhuǎn)義字符反斜杠\的代替方法及repalceAll內(nèi)涵解析
這篇文章主要介紹了Java中轉(zhuǎn)義字符反斜杠\的代替方法及repalceAll內(nèi)涵解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2019-08-08Mybatis-plus apply函數(shù)使用場景分析
Mybatis-plus 里面的 apply方法 是用于拼接自定義的條件判斷,自定義時間查詢,根據(jù)傳進來的開始日期,查詢所有該日期是數(shù)據(jù),但是數(shù)據(jù)庫中保存是時間,所以需要使用apply查詢方式并格式化,這篇文章給大家介紹Mybatis-plus apply函數(shù)使用,感興趣的朋友一起看看吧2024-02-02ShardingSphere JDBC強制路由使用的項目實踐
在某些特定場景下,可能需要繞過分片規(guī)則直接定位到特定的數(shù)據(jù)庫或表,這種情況下就可以使用HintRouting,本文就來介紹一下ShardingSphere JDBC強制路由使用的項目實踐,感興趣的可以了解一下2024-06-06