zoukankan      html  css  js  c++  java
  • Spring通过在META-INF/spring.handlers中的属性进行配置文件解析

    在Spring的入口函数refresh()之中进行的。  

    1. AbstractApplicationContext  
    2. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//获得一个新的beanFactory,并进行一些相关的load  
    3. protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {  
    4.         refreshBeanFactory();//通知子类context刷新内部的BeanFactory  
    5.         ConfigurableListableBeanFactory beanFactory = getBeanFactory();  
    6. if (logger.isDebugEnabled()) {  
    7.             logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);  
    8.         }  
    9. return beanFactory;  
    10.     }  
    11. AbstractRefreshableApplicationContext  
    12. protected final void refreshBeanFactory() throws BeansException {  
    13. if (hasBeanFactory()) {  
    14.             destroyBeans();//销毁当前context管理的所有bean  
    15.             closeBeanFactory();//关闭beanFactory  
    16.         }  
    17. try {//创建一个新的beanFactory(DefaultListableBeanFactory)  
    18.             DefaultListableBeanFactory beanFactory = createBeanFactory();  
    19.             beanFactory.setSerializationId(getId());  
    20.             customizeBeanFactory(beanFactory);  
    21.             loadBeanDefinitions(beanFactory);//加载BeanDefinition  
    22. synchronized (this.beanFactoryMonitor) {  
    23. this.beanFactory = beanFactory;  
    24.             }  
    25.         }  
    26. //...  
    27.     }  
    28. XmlWebApplicationContext  
    29. protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {  
    30. // Create a new XmlBeanDefinitionReader for the given BeanFactory.  
    31. //创建一个新的XmlBeanDefinitionReader  
    32.         XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);  
    33. // Configure the bean definition reader with this context's  
    34. // resource loading environment.  
    35.         beanDefinitionReader.setEnvironment(this.getEnvironment());  
    36.         beanDefinitionReader.setResourceLoader(this);  
    37.         beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));  
    38. // Allow a subclass to provide custom initialization of the reader,  
    39. // then proceed with actually loading the bean definitions.  
    40.         initBeanDefinitionReader(beanDefinitionReader);  
    41.         loadBeanDefinitions(beanDefinitionReader);//接着加载BeanDefinition  
    42.     }  
    43. protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {  
    44.         String[] configLocations = getConfigLocations();//获得ServletConfig的配置文件位置  
    45. if (configLocations != null) {  
    46. for (String configLocation : configLocations) {  
    47.                 reader.loadBeanDefinitions(configLocation);//根据位置加载BeanDefinition  
    48.             }  
    49.         }  
    50.     }  
    51. 中间省略  
    52. XmlBeanDefinitionReader  
    53. public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {  
    54.         BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();  
    55.         documentReader.setEnvironment(this.getEnvironment());  
    56. int countBefore = getRegistry().getBeanDefinitionCount();  
    57.         documentReader.registerBeanDefinitions(doc, createReaderContext(resource));//创建一个ReaderContext,  
    58. //注册BeanDefinition  
    59. return getRegistry().getBeanDefinitionCount() - countBefore;  
    60.     }  
    61. protected XmlReaderContext createReaderContext(Resource resource) {  
    62. if (this.namespaceHandlerResolver == null) {//创建默认的名称控件处理器解析器  
    63. this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver();  
    64.         }//返回创建好的xmlReaderContext,将创建好的namespaceHandlerResolver传入  
    65. return new XmlReaderContext(resource, this.problemReporter, this.eventListener,  
    66. this.sourceExtractor, this, this.namespaceHandlerResolver);  
    67.     }  
    68. protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {//对应的NamespaceHandlerResolver  
    69. return new DefaultNamespaceHandlerResolver(getResourceLoader().getClassLoader());  
    70.     }  
    71. public DefaultNamespaceHandlerResolver(ClassLoader classLoader) {  
    72. this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION);//这个位置就在META-INF/spring.handlers  
    73.     }  
    74. 接着往下走注册BeanDefinitioni的过程  
    75. DefaultBeanDefinitionDocumentReader  
    76. public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {  
    77. this.readerContext = readerContext;  
    78.         logger.debug("Loading bean definitions");  
    79.         Element root = doc.getDocumentElement();  
    80.         doRegisterBeanDefinitions(root);//注册beanDefinition 将root根节点传入  
    81.     }  
    82. protected void doRegisterBeanDefinitions(Element root) {  
    83. //....  
    84. this.delegate = createDelegate(this.readerContext, root, parent);//创建一个委托  
    85.         preProcessXml(root);  
    86.         parseBeanDefinitions(root, this.delegate);//处理  
    87.         postProcessXml(root);  
    88. this.delegate = parent;  
    89.     }  
    90. protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {  
    91. if (delegate.isDefaultNamespace(root)) {  
    92.             NodeList nl = root.getChildNodes();  
    93. for (int i = 0; i < nl.getLength(); i++) {  
    94.                 Node node = nl.item(i);  
    95. if (node instanceof Element) {  
    96.                     Element ele = (Element) node;  
    97. if (delegate.isDefaultNamespace(ele)) {  
    98.                         parseDefaultElement(ele, delegate);  
    99.                     }  
    100. else {  
    101.                         delegate.parseCustomElement(ele);//解析自定义的节点  
    102.                     }  
    103.                 }  
    104.             }  
    105.         }  
    106. else {  
    107.             delegate.parseCustomElement(root);  
    108.         }  
    109.     }  
    110. public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {//null  
    111.         String namespaceUri = getNamespaceURI(ele);//根据之前设置的解析器对这个uri进行解析,获得一个NamespaceHandler  
    112. //通过键值对的形式存在文件里面,在resolve里面对类名获取,然后实例化一个handler对象  
    113.                  NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);  
    114. //....现在可以对配置文件进行解析了。  
    115. return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));  
    116.     }  
    117. DefaultNamespaceHandlerResolver  
    118. public NamespaceHandler resolve(String namespaceUri) {  
    119.         Map<String, Object> handlerMappings = getHandlerMappings();  
    120.         Object handlerOrClassName = handlerMappings.get(namespaceUri);//获取处理器的类名  
    121. if (handlerOrClassName == null) {  
    122. return null;  
    123.         }  
    124. else if (handlerOrClassName instanceof NamespaceHandler) {  
    125. return (NamespaceHandler) handlerOrClassName;  
    126.         }  
    127. else {  
    128.             String className = (String) handlerOrClassName;  
    129. try {//利用反射根据类名进行类的装载  
    130.                 Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);  
    131. if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {  
    132. throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +  
    133. "] does not implement the [" + NamespaceHandler.class.getName() + "] interface");  
    134.                 }//根据类进行实例化  
    135.                 NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);  
    136.                 namespaceHandler.init();  
    137.                 handlerMappings.put(namespaceUri, namespaceHandler);//缓存这个handler,下次其他的可以再次利用  
    138. return namespaceHandler;  
    139.             }  
    140. //....  
    141.         }  
    142.     }  
  • 相关阅读:
    effective C++
    bat取时间间隔
    bat设置windows计划任务
    listener.ora 与 tnsnames.ora
    route(windows)
    bat 数组实现
    非const引用参数传入不同类型编译不过的理解(拒绝将临时对象绑定为非const的引用的形参是有道理的)
    python no module named builtins
    Caffe使用新版本CUDA和CuDNN
    Ubuntu16.04安装vim8
  • 原文地址:https://www.cnblogs.com/wwjldm/p/10338418.html
Copyright © 2011-2022 走看看