Spring的XML解析原理,这一次全搞懂再走( 四 )
这个方法中主要将xml配置加载到存中并封装成为Resource对象 , 这一步不重要 , 可以略过 , 主要的还是loadBeanDefinitions方法 , 最终还是调用到子类XmlBeanDefinitionReader的方法:
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {try {//获取Resource对象中的xml文件流对象InputStream inputStream = encodedResource.getResource().getInputStream();try {//InputSource是jdk中的sax xml文件解析对象InputSource inputSource = new InputSource(inputStream);if (encodedResource.getEncoding() != null) {inputSource.setEncoding(encodedResource.getEncoding());}//主要看这个方法return doLoadBeanDefinitions(inputSource, encodedResource.getResource());}finally {inputStream.close();}} } protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)throws BeanDefinitionStoreException {try {//把inputSource 封装成Document文件对象 , 这是jdk的APIDocument doc = doLoadDocument(inputSource, resource);//主要看这个方法 , 根据解析出来的document对象 , 拿到里面的标签元素封装成BeanDefinitionint count = registerBeanDefinitions(doc, resource);if (logger.isDebugEnabled()) {logger.debug("Loaded " + count + " bean definitions from " + resource);}return count;} } public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {// 创建DefaultBeanDefinitionDocumentReader对象 , 并委托其做解析注册工作BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();int countBefore = getRegistry().getBeanDefinitionCount();//主要看这个方法 , 需要注意createReaderContext方法中创建的几个对象documentReader.registerBeanDefinitions(doc, createReaderContext(resource));return getRegistry().getBeanDefinitionCount() - countBefore; } public XmlReaderContext createReaderContext(Resource resource) {// XmlReaderContext对象中保存了XmlBeanDefinitionReader对象和DefaultNamespaceHandlerResolver对象的引用 , 在后面会用到return new XmlReaderContext(resource, this.problemReporter, this.eventListener,this.sourceExtractor, this, getNamespaceHandlerResolver()); }
接着看看DefaultBeanDefinitionDocumentReader中是如何解析的:
protected void doRegisterBeanDefinitions(Element root) {// 创建了BeanDefinitionParserDelegate对象BeanDefinitionParserDelegate parent = this.delegate;this.delegate = createDelegate(getReaderContext(), root, parent);// 如果是Spring原生命名空间 , 首先解析 profile标签 , 这里不重要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);// We cannot use Profiles.of(...) since profile expressions are not supported// in XML config. See SPR-12458 for details.if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {if (logger.isDebugEnabled()) {logger.debug("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; }
- 多就是好吗?解析智能手机多摄发展困局
- 新基建下,系统集成商数字化建设及渠道管理深度解析
- 四个维度解析区域发展与治理
- 基于Spring+Angular9+MySQL开发平台
- 智媒视角看深圳用数据解析城市
- “联邦的战斗力量”再现,华硕Z490主板机动战士高达版解析
- 天翼云全国首个工业互联网平台二级解析节点上线
- 在美国当快递小哥赚钱吗?西瓜视频解析除了努力,运气也很重要
- 蚂蚁庄园月有阴晴圆缺答案解析 12月18日今天支付宝蚂蚁庄园答案大全
- 如何做到性能翻倍 NVIDIA Ampere架构解析