从 DispatcherServlet 类开始看。
org.springframework.web.servlet.HttpServletBean#init
initServletBean()
org.springframework.web.servlet.FrameworkServlet#initServletBean
this.webApplicationContext = initWebApplicationContext();
org.springframework.web.servlet.FrameworkServlet#initWebApplicationContext
configureAndRefreshWebApplicationContext(cwac);
org.springframework.web.servlet.FrameworkServlet#configureAndRefreshWebApplicationContext
wac.refresh();
org.springframework.context.support.AbstractApplicationContext#refresh
//xml解析
//注解的解析
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
org.springframework.context.support.AbstractApplicationContext#obtainFreshBeanFactory
refreshBeanFactory();
org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory
//实现类有xml解析和注解的解析
loadBeanDefinitions(beanFactory);
org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)
loadBeanDefinitions(beanDefinitionReader);
org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)
//xml文件变为 Resource 对象后,解析
reader.loadBeanDefinitions(configResources);
org.springframework.beans.factory.support.AbstractBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource…)
for (Resource resource : resources) {// xml 解析counter += loadBeanDefinitions(resource);
}
org.springframework.beans.factory.xml.XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource)
return loadBeanDefinitions(new EncodedResource(resource));
org.springframework.beans.factory.xml.XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.support.EncodedResource)
try {//文件流InputStream inputStream = encodedResource.getResource().getInputStream();try {// InputSource 是 dk 中的 xml 解析对象InputSource inputSource = new InputSource(inputStream);if (encodedResource.getEncoding() != null) {inputSource.setEncoding(encodedResource.getEncoding());}// xml 解析return doLoadBeanDefinitions(inputSource, encodedResource.getResource());}finally {inputStream.close();}}
org.springframework.beans.factory.xml.XmlBeanDefinitionReader#doLoadBeanDefinitions
try {// xml 解析为 Document 对象Document doc = doLoadDocument(inputSource, resource);return registerBeanDefinitions(doc, resource);}
org.springframework.beans.factory.xml.XmlBeanDefinitionReader#registerBeanDefinitions
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {//xml 文档解析器BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();int countBefore = getRegistry().getBeanDefinitionCount();documentReader.registerBeanDefinitions(doc, createReaderContext(resource));return getRegistry().getBeanDefinitionCount() - countBefore;}
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#registerBeanDefinitions
xml 文件中的根节点&#xff0c;即 <beans>
Element root &#61; doc.getDocumentElement();
doRegisterBeanDefinitions(root);
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions
parseBeanDefinitions(root, this.delegate);
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {if (delegate.isDefaultNamespace(root)) {NodeList nl &#61; root.getChildNodes();for (int i &#61; 0; i < nl.getLength(); i&#43;&#43;) {Node node &#61; nl.item(i);if (node instanceof Element) {Element ele &#61; (Element) node;if (delegate.isDefaultNamespace(ele)) {//解析 xml 中默认的元素&#xff0c;默认标签&#xff1a;import 、alias、bean、beansparseDefaultElement(ele, delegate);}else {// 解析 xml 中 自定义的元素delegate.parseCustomElement(ele);}}}}else {delegate.parseCustomElement(root);}}
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseDefaultElement
// bean 标签解析
processBeanDefinition(ele, delegate);
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#processBeanDefinition
BeanDefinitionHolder bdHolder &#61; delegate.parseBeanDefinitionElement(ele);
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseBeanDefinitionElement(org.w3c.dom.Element, org.springframework.beans.factory.config.BeanDefinition)
String beanName &#61; id;
AbstractBeanDefinition beanDefinition &#61;
parseBeanDefinitionElement(ele, beanName, containingBean);
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseBeanDefinitionElement(org.w3c.dom.Element, java.lang.String, org.springframework.beans.factory.config.BeanDefinition)
AbstractBeanDefinition bd &#61;
createBeanDefinition(className, parent);
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#createBeanDefinition
return BeanDefinitionReaderUtils.createBeanDefinition(parentName, className,this.readerContext.getBeanClassLoader());
org.springframework.beans.factory.support.BeanDefinitionReaderUtils#createBeanDefinition
GenericBeanDefinition bd &#61; new GenericBeanDefinition();bd.setParentName(parentName);if (className !&#61; null) {if (classLoader !&#61; null) {// 获取 class 元素配置的类bd.setBeanClass(ClassUtils.forName(className, classLoader));}else {bd.setBeanClassName(className);}}return bd;
返回到
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseBeanDefinitionElement(org.w3c.dom.Element, java.lang.String, org.springframework.beans.factory.config.BeanDefinition)
//得到 BeanDefinition 对象
AbstractBeanDefinition bd &#61; createBeanDefinition(className, parent);
//bean 标签上的元素解析&#xff0c;并封装到 db 中&#xff0c;即 BeanDefinition 对象中
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
BeanDefinition 对象
- 会把 xml 中的标签元素&#xff0c;比如 bean,componentScan,annotation-config 标签中的元素信息封装成 BeanDefinition 对象&#xff0c;
- 会把 annotation &#xff0c;比如 &#64;Service、&#64;Controller、&#64;Component、&#64;Resource 等注解的类&#xff0c;封装成 BeanDefinition 对象
返回到
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseBeanDefinitionElement(org.w3c.dom.Element, org.springframework.beans.factory.config.BeanDefinition)
AbstractBeanDefinition beanDefinition &#61; parseBeanDefinitionElement(ele, beanName, containingBean);
返回到
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#processBeanDefinition
返回到
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions
// 自定义标签解析
delegate.parseCustomElement(ele);
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseCustomElement(org.w3c.dom.Element)
return parseCustomElement(ele, null);
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseCustomElement(org.w3c.dom.Element, org.springframework.beans.factory.config.BeanDefinition)
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {//元素的对应的 NamespaceURIString namespaceUri &#61; getNamespaceURI(ele);//根据 NamespaceURI 拿到到应的处理类&#xff0c;即 NamespaceHandler NamespaceHandler handler &#61; this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);if (handler &#61;&#61; null) {error("Unable to locate Spring NamespaceHandler for XML schema namespace [" &#43; namespaceUri &#43; "]", ele);return null;}return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));}
NamespaceURI 就是 beans 标签的 xmlns 、 xmlns:context、xmlns:aop、xmlns:tx 后面uri
org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#resolve
Map<String, Object> handlerMappings &#61; getHandlerMappings();
org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#getHandlerMappings
//加载所有的配置文件
Properties mappings &#61;
PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader);Map<String, Object> handlerMappings &#61; new ConcurrentHashMap<String, Object>(mappings.size());
CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings);
//返回这个 map,
this.handlerMappings &#61; handlerMappings;
查看 4.3.12.RELEASE\spring-context-4.3.12.RELEASE.jar!\META-INF\spring.handlers
注册 spring context 自定义标签解析器 org.springframework.context.config.ContextNamespaceHandler
查看 spring-webmvc-4.3.12.RELEASE.jar!\META-INF\spring.handlers
注册 spring mvc 自定义的标签解析器 org.springframework.web.servlet.config.MvcNamespaceHandler
返回到
org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#resolve
Map<String, Object> handlerMappings &#61; getHandlerMappings();
Object handlerOrClassName &#61; handlerMappings.get(namespaceUri);
// 例如&#xff1a;handlerOrClassName 就是指 ContextNamespaceHandler
String className &#61; (String) handlerOrClassName;
// new 出 ContextNamespaceHandler 的实例
NamespaceHandler namespaceHandler &#61; (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
// 调用注册方法&#xff0c;注册自定义标签的解析器
namespaceHandler.init();
//返回
return namespaceHandler;
返回到
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseCustomElement(org.w3c.dom.Element, org.springframework.beans.factory.config.BeanDefinition)
String namespaceUri &#61; getNamespaceURI(ele);
NamespaceHandler handler &#61;
this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
org.springframework.beans.factory.xml.NamespaceHandlerSupport#parse
// 根据标签找到到应的解析器&#xff0c;再调用 parse 方法解析标签&#xff0c;即 element
return findParserForElement(element, parserContext).parse(element, parserContext);
org.springframework.beans.factory.xml.NamespaceHandlerSupport#findParserForElement
//得到标签对就的处理类
String localName &#61; parserContext.getDelegate().getLocalName(element);
BeanDefinitionParser parser &#61; this.parsers.get(localName);
return parser;