1. xml方式提供者启动代码
?2.跟踪ClassPathXmlApplicationContext#refresh()方法。
3.
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
4.obtainFreshBeanFactory()方法加载bean定义。
5.其中newResourceEntityResolver(this)通过PluggableSchemaResolver读取META-INF/spring.schemas文件内容。会加载所有该目录下的键值对内容放在map里。loadBeanDefinitions(beanDefinitionReader); 会继续执行,寻找到默认命名空间处理解析器DefaultNamespaceHandlerResolver.它去寻找/META-INF/spring.handlers文件。文件内容



/**
* Parse the elements at the root level in the document:
* "import", "alias", "bean".
* @param root the DOM root element of the document
*/
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
//执行自定义元素
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
/**
* Parse a custom element (outside of the default namespace).
* @param ele the element to parse
* @return the resulting bean definition
*/
@Nullable
public BeanDefinition parseCustomElement(Element ele) {
return parseCustomElement(ele, null);
}
/**
* Parse a custom element (outside of the default namespace).
* @param ele the element to parse
* @param containingBd the containing bean definition (if any)
* @return the resulting bean definition
*/
@Nullable
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
String namespaceUri = getNamespaceURI(ele);
if (namespaceUri == null) {
return null;
}
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
//执行DubboNamespaceHandler
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
?NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); //执行DubboNamespaceHandler的init方法。然后解析每个元素。handler.parse(ele,new ParserContext(this.readerContext,this,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
*/
@Override
@Nullable
public NamespaceHandler resolve(String namespaceUri) {
//获取handlerMappings
Map<String, Object> handlerMappings = getHandlerMappings();
Object handlerOrClassName = handlerMappings.get(namespaceUri);
if (handlerOrClassName == null) {
return null;
}
else if (handlerOrClassName instanceof NamespaceHandler) {
return (NamespaceHandler) handlerOrClassName;
}
else {
String className = (String) handlerOrClassName;
try {
Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +
"] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
}
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
namespaceHandler.init();
handlerMappings.put(namespaceUri, namespaceHandler);
return namespaceHandler;
}
catch (ClassNotFoundException ex) {
throw new FatalBeanException("Could not find NamespaceHandler class [" + className +
"] for namespace [" + namespaceUri + "]", ex);
}
catch (LinkageError err) {
throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" +
className + "] for namespace [" + namespaceUri + "]", err);
}
}
}
/**
* Load the specified NamespaceHandler mappings lazily.
*/
private Map<String, Object> getHandlerMappings() {
Map<String, Object> handlerMappings = this.handlerMappings;
if (handlerMappings == null) {
synchronized (this) {
handlerMappings = this.handlerMappings;
if (handlerMappings == null) {
if (logger.isTraceEnabled()) {
logger.trace("Loading NamespaceHandler mappings from [" + this.handlerMappingsLocation + "]");
}
try {
Properties mappings =
PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader);
if (logger.isTraceEnabled()) {
logger.trace("Loaded NamespaceHandler mappings: " + mappings);
}
handlerMappings = new ConcurrentHashMap<>(mappings.size());
CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings);
this.handlerMappings = handlerMappings;
}
catch (IOException ex) {
throw new IllegalStateException(
"Unable to load NamespaceHandler mappings from location [" + this.handlerMappingsLocation + "]", ex);
}
}
}
}
return handlerMappings;
}

?
然后执行DubboNamespaceHandler 的init方法,并解析。

然后执行后续流程prepareBeanFactory(beanFactory);

在写spring 加载spring.schemas时,不明白从哪里加载细节,我把代码调试出来。
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
Enumeration<URL> urls = (context.getClassLoader() != null ? context.getClassLoader().getResources("META-INF/spring.schemas") :
ClassLoader.getSystemResources("META-INF/spring.schemas"));
Properties props = new Properties();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
System.out.println("url = " + url);
URLConnection con = url.openConnection();
ResourceUtils.useCachesIfNecessary(con);
try (InputStream is = con.getInputStream()) {
if ("META-INF/spring.schemas".endsWith(".xml")) {
props.loadFromXML(is);
}
else {
props.load(is);
}
}
}
System.out.println("props.size() = " + props.size());

后面参考了https://www.jianshu.com/p/f78b4b4435c2 ,觉得写的不错。这个只是从宏观方面说的。
觉得文章不错,dubbo暴露服务的
https://www.jianshu.com/p/7b8391130ae4 https://www.jianshu.com/p/7b8391130ae4
|