spring源码解析(一)
发布日期:2021-10-18 18:51:28
浏览次数:2
分类:技术文章
本文共 19525 字,大约阅读时间需要 65 分钟。
XmlBeanFactory使用了DefaultListableBeanFactory作为基类,DefaultListableBeanFactory是一个很重要的IOC实现类,XmlBeanFactory其实现基本原理和ApplicationContext一样,也都是通过持有或者扩展DefaultListableBeanFactory来获得基本的IOC功能。
public void testXmlBeanfactory() throws Exception { XmlBeanFactory xmlBeanFactory=new XmlBeanFactory(COLLECTIONS_XSD_CONTEXT); xmlBeanFactory.preInstantiateSingletons(); }
XmlBeanFactory资源注入
package org.springframework.beans.factory.xml;import org.springframework.beans.BeansException;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.support.DefaultListableBeanFactory;import org.springframework.core.io.Resource;/** * 方便扩展的{@link DefaultListableBeanFactory}从XML文档读取Bean定义. * 委托 to {@link XmlBeanDefinitionReader} 形式; **/@Deprecated@SuppressWarnings({ "serial", "all"})public class XmlBeanFactory extends DefaultListableBeanFactory { private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this); /** * 创建一个新的XmlBeanFactory用给定的资源,必须使用DOM解析. * @param resource XML资源加载bean定义 * @throws BeansException 在加载或解析错误 */ public XmlBeanFactory(Resource resource) throws BeansException { this(resource, null); } /** * 创建一个新的Xml Bean工厂用给定的输入流,必须使用DOM解析。 * @param resource XML资源加载bean定义 * @param parentBeanFactory 上级bean工厂 * @throws BeansException 在加载或解析错误 */ public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException { super(parentBeanFactory); this.reader.loadBeanDefinitions(resource); }}
由XmlBeanDefinitionReader载入XML文件的形式,通过回调配置BeanFactory
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { private final ThreadLocal> resourcesCurrentlyBeingLoaded = new NamedThreadLocal >("XML bean definition resources currently being loaded");/** * 从指定的XML文件加载bean定义。 * @param resource 资源的XML文件描述 * @return bean定义发现的数量 * @throws BeanDefinitionStoreException 在加载或解析错误 */ @Override public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException { return loadBeanDefinitions(new EncodedResource(resource)); } /** * 从指定的XML文件加载bean定义。 * @param encodedResource 资源的XML文件描述,允许指定一个编码使用解析该文件 * @return bean定义发现的数量 * @throws BeanDefinitionStoreException 在加载或解析错误 */ public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { Assert.notNull(encodedResource, "EncodedResource must not be null"); if (logger.isInfoEnabled()) { logger.info("Loading XML bean definitions from " + encodedResource.getResource()); } //ThreadLocal初始化 Set currentResources = this.resourcesCurrentlyBeingLoaded.get(); if (currentResources == null) { currentResources = new HashSet (4); this.resourcesCurrentlyBeingLoaded.set(currentResources); } if (!currentResources.add(encodedResource)) { throw new BeanDefinitionStoreException( "Detected cyclic loading of " + encodedResource + " - check your import definitions!"); } try { InputStream inputStream = encodedResource.getResource().getInputStream(); try { InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } finally { inputStream.close(); } } catch (IOException ex) { throw new BeanDefinitionStoreException( "IOException parsing XML document from " + encodedResource.getResource(), ex); } finally { currentResources.remove(encodedResource); if (currentResources.isEmpty()) { this.resourcesCurrentlyBeingLoaded.remove(); } } } /** * 实际上从指定的加载bean定义XML文件。 * @param inputSource SAX读取输入源 * @param resource 资源的XML文件描述 * @return bean定义发现的数量 * @throws BeanDefinitionStoreException 在加载或解析错误 */ protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { //实际上使用配置文件加载器加载指定的文档。 Document doc = doLoadDocument(inputSource, resource); //注册的bean定义包含在给定的DOM文档。 return registerBeanDefinitions(doc, resource); } catch (BeanDefinitionStoreException ex) { throw ex; } catch (SAXParseException ex) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex); } catch (SAXException ex) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", ex); } catch (ParserConfigurationException ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, ex); } catch (IOException ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, ex); } catch (Throwable ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, ex); } } /** * 注册的bean定义包含在给定的DOM文档。 * 创建一个新的解析器类的实例,并调用 * @param doc DOM文档 * @param resource 上下文信息资源描述(对上下文信息) * @return * @throws BeanDefinitionStoreException */ public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { //实例化: DefaultBeanDefinitionDocumentReader BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); //获取bean注册表-》或者注册数量 int countBefore = getRegistry().getBeanDefinitionCount(); //注册 documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); return getRegistry().getBeanDefinitionCount() - countBefore; } /** * 创建BeanDefinitionDocumentReader用于从XML文档读取bean定义 * 默认实现实例化指定的"documentReaderClass" * @return */ protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() { return BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass)); }}
AbstractBeanDefinitionReader
抽象基类实现为bean定义的读者public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable, BeanDefinitionReader { private final BeanDefinitionRegistry registry; /** * 实例化时指定的工厂 * @return */ @Override public final BeanDefinitionRegistry getRegistry() { return this.registry; }}
public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader { /** * 实现解析bean定义 */ @Override public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; logger.debug("Loading bean definitions"); Element root = doc.getDocumentElement(); doRegisterBeanDefinitions(root); } /** * 登记每个bean定义在给定的根 * Register each bean definition within the given root {@code} element. */ protected void doRegisterBeanDefinitions(Element root) { // Any nested elements will cause recursion in this method. In // order to propagate and preserve default-* attributes correctly, // keep track of the current (parent) delegate, which may be null. Create // the new (child) delegate with a reference to the parent for fallback purposes, // then ultimately reset this.delegate back to its original (parent) reference. // this behavior emulates a stack of delegates without actually necessitating one. // 任何嵌套的< bean >元素将导致该方法递归。 // 在以传播和保存< bean >默认- *属性正确,跟踪当前(父)委托,这可能是null。 // 创建新(孩子)代表一个参考到父回退的目的,最终重置。 // 委托回到原来的(父母)参考。这种行为模拟一堆代表不需要。 BeanDefinitionParserDelegate parent = this.delegate; //创建上级委托 this.delegate = createDelegate(getReaderContext(), root, parent); if (this.delegate.isDefaultNamespace(root)) { String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); if (StringUtils.hasText(profileSpec)) { String[] specifiedProfiles = StringUtils.tokenizeToStringArray( profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { if (logger.isInfoEnabled()) { logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + getReaderContext().getResource()); } return; } } } preProcessXml(root); //解析 parseBeanDefinitions(root, this.delegate); postProcessXml(root); this.delegate = parent; } /** * 解析文档中的根级别的元素:"import", "alias", "bean". * @param root DOM文档的根元素 * @param delegate */ 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)) { //解析默认元素 class parseDefaultElement(ele, delegate); } else { //解析定制元素 util list工具 delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } } private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); } else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // recurse doRegisterBeanDefinitions(ele); } } /** * 注册与给定的bean工厂给定的bean定义 * @param definitionHolder bean定义包括名和别名 * @param registry 注册的bean工厂 * @throws BeanDefinitionStoreException */ protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { //装饰属性 bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // Register the final decorated instance.注册最后装饰实例。 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex); } // Send registration event.发送注册事件 getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }}
有状态委托类用于解析XML bean定义。用于使用主要的解析器和任何扩展
public class BeanDefinitionParserDelegate { public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder) { return decorateBeanDefinitionIfRequired(ele, definitionHolder, null); } public BeanDefinitionHolder decorateBeanDefinitionIfRequired( Element ele, BeanDefinitionHolder definitionHolder, BeanDefinition containingBd) { BeanDefinitionHolder finalDefinition = definitionHolder; // Decorate based on custom attributes first. //装修首先基于自定义属性。 NamedNodeMap attributes = ele.getAttributes(); for (int i = 0; i < attributes.getLength(); i++) { Node node = attributes.item(i); finalDefinition = decorateIfRequired(node, finalDefinition, containingBd); } // Decorate based on custom nested elements. //装饰基于自定义嵌套的元素。 NodeList children = ele.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node node = children.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { finalDefinition = decorateIfRequired(node, finalDefinition, containingBd); } } return finalDefinition; }}
/** * 实用程序方法,有助于读者实现bean定义。 * Utility methods that are useful for bean definition reader implementations. * Mainly intended for internal use. * 主要用于内部使用. * * @author Juergen Hoeller * @author Rob Harrop * @see PropertiesBeanDefinitionReader * @see org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader * @since 1.1 */public class BeanDefinitionReaderUtils { /** * 注册与给定的bean工厂给定的bean定义 * @param definitionHolder bean定义包括名和别名 * @param registry 注册的bean工厂 * @throws BeanDefinitionStoreException */ public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { // Register bean definition under primary name. //主要的名义注册的bean定义。 String beanName = definitionHolder.getBeanName(); //注册bean registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); // Register aliases for bean name, if any. 注册别名 String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String alias : aliases) { registry.registerAlias(beanName, alias); } } }}
默认Bean实现工厂
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { /** Map from serialized id to factory instance */ private static final Map> serializableFactories = new ConcurrentHashMap >(8); /** Optional id for this factory, for serialization purposes */ private String serializationId; /** Whether to allow re-registration of a different definition with the same name */ private boolean allowBeanDefinitionOverriding = true; /** Whether to allow eager class loading even for lazy-init beans */ private boolean allowEagerClassLoading = true; /** Optional OrderComparator for dependency Lists and arrays */ private Comparator
转载地址:https://blog.csdn.net/u011153869/article/details/70597582 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
能坚持,总会有不一样的收获!
[***.219.124.196]2024年03月26日 18时26分42秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
开发中文 API 的一些策略
2019-04-26
从日本编程书籍《我的第一本编程书》中译版看中文例程如何扬长避短——标识符(一)
2019-04-26
中文命名标识符如何区分类型和变量
2019-04-26
编程术语成系统中文化的意义
2019-04-26
草蟒 Python 中文 API 与 IDE 支持尝鲜
2019-04-26
一种改进中文 API 可读性的方法:参数不限于在末尾
2019-04-26
中文编程开发工具的生存模式探讨
2019-04-26
写给木兰编程语言研发团队的公开信
2019-04-26
为什么要急着为「木兰」编程语言贴上“造假”的标签?
2019-04-26
编程语言国产化的关键一战——对肆意污名化“木兰”编程语言说“不”
2019-04-26
各大媒体对「木兰」编程语言的不当言论盘点
2019-04-26
戳破针对「木兰」编程语言的拙劣谣言
2019-04-26
为「木兰」编程语言添加对中文命名标识符的支持
2019-04-26
悬赏万元,重现「木兰」编程语言编译器
2019-04-26
跳出编程语言本身看中文编程语言设计
2019-04-26
RPLY 入门例程中文化
2019-04-26
木兰编程语言入门教程之一——浅介
2019-04-26
木兰编程语言入门教程之二——控制走向
2019-04-26
基于「木兰」编译器,加十行代码实现 ∈ (属于集合)语法
2019-04-26
创建安卓键盘演示——“好不”
2019-04-26