new XmlBeanFactory(new ClassPathXml(“test.xml”));
加载流程梗概。 详情还需要参照Spring源码(3.2.16)。
XmlBeanFactory(Resource resource) {
/**
* Load bean definitions from the specified XML file. 从指定的XML文件加载bean定义
* @param resource the resource descriptor for the XML file
* @return the number of bean definitions found
* @throws BeanDefinitionStoreException in case of loading or parsing errors
*/
loadBeanDefinitions(Resource resource) {
/**
* Load bean definitions from the specified XML file.
* @param encodedResource the resource descriptor for the XML file,
* allowing to specify an encoding to use for parsing the file
* @return the number of bean definitions found
* @throws BeanDefinitionStoreException in case of loading or parsing errors
*/
loadBeanDefinitions(EncodedResource encodedResource) {
/**
* Actually load bean definitions from the specified XML file.
* @param inputSource the SAX InputSource to read from
* @param resource the resource descriptor for the XML file
* @return the number of bean definitions found
* @throws BeanDefinitionStoreException in case of loading or parsing errors
*/
doLoadBeanDefinitions(InputSource inputSource, Resource resource) {
/**
* Gets the validation mode for the specified {@link Resource}. If no explicit
* validation mode has been configured then the validation mode is
* {@link #detectValidationMode detected}.
* <p>Override this method if you would like full control over the validation
* mode, even when something other than {@link #VALIDATION_AUTO} was set.
*/
//DTD OR XSD
getValidationModeForResource(Resource resource) {
/**
* Return the validation mode to use.
*/
getValidationMode()
/**
* Detects which kind of validation to perform on the XML file identified
* by the supplied {@link Resource}. If the file has a {@code DOCTYPE}
* definition then DTD validation is used otherwise XSD validation is assumed.
* <p>Override this method if you would like to customize resolution
* of the {@link #VALIDATION_AUTO} mode.
*/
detectValidationMode(Resource resource)
}
/**
* Register the bean definitions contained in the given DOM document.
* Called by {@code loadBeanDefinitions}.
* <p>Creates a new instance of the parser class and invokes
* {@code registerBeanDefinitions} on it.
* @param doc the DOM document
* @param resource the resource descriptor (for context information)
* @return the number of bean definitions found
* @throws BeanDefinitionStoreException in case of parsing errors
* @see #loadBeanDefinitions
* @see #setDocumentReaderClass
* @see BeanDefinitionDocumentReader#registerBeanDefinitions
*/
registerBeanDefinitions(Document doc, Resource resource) {
/**
* Read bean definitions from the given DOM document and
* register them with the registry in the given reader context.
* @param doc the DOM document
* @param readerContext the current context of the reader
* (includes the target registry and the resource being parsed)
* @throws BeanDefinitionStoreException in case of parsing errors
*/
registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
/**
* Register each bean definition within the given root {@code <beans/>} element.
*/
doRegisterBeanDefinitions(Element root){
/**
* Allow the XML to be extensible by processing any custom element types first,
* before we start to process the bean definitions. This method is a natural
* extension point for any other custom pre-processing of the XML.
* <p>The default implementation is empty. Subclasses can override this method to
* convert custom elements into standard Spring bean definitions, for example.
* Implementors have access to the parser's bean definition reader and the
* underlying XML resource, through the corresponding accessors.
* @see #getReaderContext()
*/
preProcessXml(Element root); //未实现,由用户自己根据实际情况实现
/**
* Parse the elements at the root level in the document:
* "import", "alias", "bean".
* @param root the DOM root element of the document
*/
parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate){
parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate){
//import标签
importBeanDefinitionResource(Element ele)
//alias标签
processAliasRegistration(Element ele)
//bean标签
/**
* Process the given bean element, parsing the bean definition
* and registering it with the registry.
*/
processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
/**
* Parses the supplied {@code <bean>} element. May return {@code null}
* if there were errors during parse. Errors are reported to the
* {@link org.springframework.beans.factory.parsing.ProblemReporter}.
*/
parseBeanDefinitionElement(Element ele){
/**
* Parse the bean definition itself, without regard to name or aliases. May return
* {@code null} if problems occurred during the parsing of the bean definition.
*/
parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean){
解析各种属性
}
}
//当Spring中的bean使用的是默认的标签配置,但是其中的子元素却使用了自定义的配置,这个就起作用了
decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder, BeanDefinition containingBd)
/**
* Register the given bean definition with the given bean factory.
* @param definitionHolder the bean definition including name and aliases
* @param registry the bean factory to register with
* @throws BeanDefinitionStoreException if registration failed
*/
registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
/**
* Register a new bean definition with this registry.
* Must support RootBeanDefinition and ChildBeanDefinition.
* @param beanName the name of the bean instance to register
* @param beanDefinition definition of the bean instance to register
* @throws BeanDefinitionStoreException if the BeanDefinition is invalid
* or if there is already a BeanDefinition for the specified bean name
* (and we are not allowed to override it)
* @see RootBeanDefinition
* @see ChildBeanDefinition
*/
// Register bean definition under primary name.
registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
/**
* Given a name, register an alias for it.
* @param name the canonical name
* @param alias the alias to be registered
* @throws IllegalStateException if the alias is already in use
* and may not be overridden
*/
// Register aliases for bean name, if any.
registerAlias(String name, String alias)
// Send registration event.
fireComponentRegistered(ComponentDefinition componentDefinition) //未实现,用户自己看着办
}
}
//beans标签
doRegisterBeanDefinitions(Element ele) // recurse
}
parseCustomElement(Element ele, BeanDefinition containingBd){
/**
* Locate the {@link NamespaceHandler} for the supplied namespace URI
* from the configured mappings.
* @param namespaceUri the relevant namespace URI
* @return the located {@link NamespaceHandler}, or {@code null} if none found
*/
resolve(String namespaceUri){
/**
* Load the specified NamespaceHandler mappings lazily.
*/
getHandlerMappings(){ //使用的是ConcurrentHashMap
synchronized(this){
/**
* Load all properties from the specified class path resource
* (in ISO-8859-1 encoding), using the given class loader.
* <p>Merges properties if more than one resource of the same name
* found in the class path.
* @param resourceName the name of the class path resource
* @param classLoader the ClassLoader to use for loading
* (or {@code null} to use the default class loader)
* @return the populated Properties instance
* @throws IOException if loading failed
*/
loadAllProperties(String resourceName, ClassLoader classLoader)
/**
* Merge the given Properties instance into the given Map,
* copying all properties (key-value pairs) over.
* <p>Uses {@code Properties.propertyNames()} to even catch
* default properties linked into the original Properties instance.
* @param props the Properties instance to merge (may be {@code null})
* @param map the target Map to merge the properties into
*/
mergePropertiesIntoMap(Properties props, Map map)
}
}
}
}
}
/**
* Allow the XML to be extensible by processing any custom element types last,
* after we finished processing the bean definitions. This method is a natural
* extension point for any other custom post-processing of the XML.
* <p>The default implementation is empty. Subclasses can override this method to
* convert custom elements into standard Spring bean definitions, for example.
* Implementors have access to the parser's bean definition reader and the
* underlying XML resource, through the corresponding accessors.
* @see #getReaderContext()
*/
postProcessXml(Element root) //未实现,由用户自己根据实际情况实现
}
}
}
}
}
}
}