`

spring4.0源码分析解析xml补充━━━(PluggableSchemaResolver类)

 
阅读更多

        上面一篇文件讲了BeanDefinition的原理。这一篇讲spring解析xml的时候一些小特点。主要是验证,然后不同的xml名称空间会有不同的类来解析xml。解析xml,spring没有用到第三方库,而是直接使用java的api。这里是和spring解析xml类似的代码。我们从这里开始。

@Test
public void testSpringReaderXml() throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setNamespaceAware(true);
		//设置解析xml的时候验证xml的格式
		factory.setValidating(true);
		factory.setAttribute(SCHEMA_LANGUAGE_ATTRIBUTE, XSD_SCHEMA_LANGUAGE);
		factory.setExpandEntityReferences(true);
		DocumentBuilder docBuilder = factory.newDocumentBuilder();
//设置解析验证实例
		docBuilder.setEntityResolver(new EntityResolver() {
			@Override
			public InputSource resolveEntity(String publicId, String systemId)
					throws SAXException, IOException {
				//验证xml时要用到的xsd文件,对应schemaLocation的value
				InputSource source = new InputSource(TestXSD.class.getResourceAsStream("D:\\workspaceStudy\\spring_study\\src\\spring-beans-3.0.xsd"));
				source.setPublicId(publicId);
				//验证xml对应的schemaLocation的key
				source.setSystemId("http://www.springframework.org/schema/beans/spring-beans-3.0.xsd");
				return source;
			}

		});
		//设置解析错误时回调方法
		docBuilder.setErrorHandler(new ErrorHandler() {

			@Override
			public void warning(SAXParseException exception)
					throws SAXException {
				exception.printStackTrace();
				throw exception;
			}

			@Override
			public void error(SAXParseException exception) throws SAXException {
				// TODO Auto-generated method stub
				exception.printStackTrace();
				throw exception;
			}

			@Override
			public void fatalError(SAXParseException exception)
					throws SAXException {
				// TODO Auto-generated method stub
				exception.printStackTrace();
				throw exception;
			}

		});

		Document document = docBuilder
				.parse("D:\\workspaceStudy\\spring_study\\src\\beanFactory2.xml");
		Element root = document.getDocumentElement();
		String nodeName = root.getNodeName();
		System.out.println("nodeName:" + nodeName + " ;namespace:"
				+ root.getNamespaceURI());
		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;
				System.out.println(ele.getLocalName() + ":"
						+ ele.getAttribute("id"));
			}
		}
		System.out.println("validate true");
}

        spring解析是直接用DocumentBuilder这个类生成Document,然后通过Document得到不同的Element,并且不同的Element,为不同的方法解析。解析xml时验证的实例就会用到PluggableSchemaResolver类。

public class PluggableSchemaResolver implements EntityResolver {

	/**
	 * The location of the file that defines schema mappings.
	 * Can be present in multiple JAR files.
	 */
	public static final String DEFAULT_SCHEMA_MAPPINGS_LOCATION = "META-INF/spring.schemas";


	private static final Log logger = LogFactory.getLog(PluggableSchemaResolver.class);

	private final ClassLoader classLoader;

	private final String schemaMappingsLocation;

	/** Stores the mapping of schema URL -> local schema path */
	private volatile Map<String, String> schemaMappings;

。。。。。
public InputSource resolveEntity(String publicId, String systemId) throws IOException {
		if (logger.isTraceEnabled()) {
			logger.trace("Trying to resolve XML entity with public id [" + publicId +
					"] and system id [" + systemId + "]");
		}

		if (systemId != null) {
			String resourceLocation = getSchemaMappings().get(systemId);
			if (resourceLocation != null) {
				Resource resource = new ClassPathResource(resourceLocation, this.classLoader);
				try {
					InputSource source = new InputSource(resource.getInputStream());
					source.setPublicId(publicId);
					source.setSystemId(systemId);
					if (logger.isDebugEnabled()) {
						logger.debug("Found XML schema [" + systemId + "] in classpath: " + resourceLocation);
					}
					return source;
				}
				catch (FileNotFoundException ex) {
					if (logger.isDebugEnabled()) {
						logger.debug("Couldn't find XML schema [" + systemId + "]: " + resource, ex);
					}
				}
			}
		}
		return null;
	}
   

}

 

上面的schemaMappings就是存放url对应的xsd地址。这里是读classpath路径下所有的META-INF/spring.schemas文件。读的方法就类似下面:

@Test
	public void testMeta() throws IOException {
		ClassLoader cld = Thread.currentThread().getContextClassLoader();
		Enumeration enumURL = cld.getResources("META-INF/spring.schemas");
		int count = 0;
		while (enumURL.hasMoreElements()) {
			URL url = (URL) enumURL.nextElement();
			count++;
			System.out.println(url.getFile());
			InputStream is = url.openConnection().getInputStream();
			int i = is.read();
			while (i != -1) {
				System.out.print((char) i);
				i = is.read();
			}
			System.out.println();
			is.close();
		}
		System.out.println(count);
	}

 

分享到:
评论

相关推荐

    spring4.0源码

    现在,我们将深入探讨Spring 4.0源码中的关键知识点。 1. **依赖注入(Dependency Injection, DI)**:Spring的核心特性之一就是DI,它通过容器管理对象及其依赖关系,使代码更加灵活和可测试。在源码中,我们可以...

    spring4.0.x源码

    本文将深入解析 Spring 4.0.x 的核心概念、主要改进以及关键组件。 一、Spring 概述 Spring 是一个全面的企业级应用开发框架,它简化了Java应用程序的开发,通过提供依赖注入(DI)和面向切面编程(AOP)等机制,...

    Spring 4.0.x源码

    通过学习Spring 4.0.x的源码,开发者不仅可以深入了解Spring的工作原理,还能学习到最佳实践和设计模式,这对于提升个人技能和解决实际问题大有裨益。深入研究每个模块的实现细节,有助于更好地利用Spring框架提供的...

    spring4.0框架demo

    《Spring 4.0框架深度探索:基于Maven构建的实战Demo》 Spring框架作为Java企业级应用开发的基石,自推出以来就以其强大的功能和灵活性赢得了广大开发者的心。Spring 4.0作为其一个重要版本,引入了许多改进和新...

    Spring4.0 jar包

    Spring4.0版本是该框架的一个重要里程碑,它引入了多项增强功能和优化,提升了性能和开发者体验。在此,我们将深入探讨Spring4.0中的关键知识点。 首先,Spring4.0对Java版本的支持升级至Java 7,这意味着开发者...

    spring4.0完整jar包

    这个"spring4.0完整jar包"包含了Spring4.0框架的所有核心组件和相关模块,使得开发者能够一站式获取所有必要的库,方便集成到项目中。 首先,让我们深入了解一下Spring框架的核心组成部分: 1. **IoC(Inversion ...

    spring 4.0.x源码

    8. **API清理**:Spring 4.0.x删除了许多已废弃的方法和类,以保持API的清洁和一致性。这种做法鼓励开发者使用最新的API,避免了依赖过时的代码。 9. **更好的类型安全**:Spring 4增强了类型安全,例如在Bean的...

    Spring4.0源代码

    4. **Java配置**:除了XML,Spring4.0引入了`@Configuration`类和`@Bean`方法,使得完全可以通过Java代码来配置应用,提高了代码的可读性和维护性。 5. **反应式编程支持**:Spring4.0开始引入对反应式编程的支持,...

    spring4.0的pom.xml

    spirng4的jar以及相关的jar依赖

    spring4.0 jar包

    4. **改进的JDBC抽象层**:Spring 4.0的JdbcTemplate和NamedParameterJdbcTemplate类进行了优化,提高了性能并降低了内存占用。同时,增加了对JDBC 4.1和4.2规范的支持,包括更好的类型处理和批处理操作。 5. **...

    spring4.0框架所需的jar包

    请注意,虽然这些jar包已经足够搭建一个基本的Spring 4.0环境,但实际开发中可能还需要根据具体需求引入其他的依赖,如对其他数据库驱动、JSON解析库、邮件服务等的支持。为了方便管理和升级,推荐使用Maven或Gradle...

    SPRING 4.0 中文指南

    Spring 4.0版本是该框架的一个重要里程碑,引入了许多改进和新特性,使得开发者能够更加高效地工作。这篇指南将深入探讨Spring 4.0的关键知识点。 一、Spring核心模块 Spring的核心模块包括IoC(Inversion of ...

    Spring4.0的jar包,官方源码,javadoc

    源码分析是提升技能的绝佳途径,Spring4.0的源码揭示了框架内部的工作机制。例如,你可以看到AOP(面向切面编程)如何实现、IoC(控制反转)容器如何管理Bean、以及事件监听和事务管理的底层逻辑。通过阅读源码,...

    Spring5 源码分析(第 2 版)-某Tom老师

    《Spring5 源码分析(第 2 版)》是某Tom老师精心编写的深度解析文档,旨在帮助读者全面理解Spring5的核心机制和设计理念。Spring作为Java领域最为广泛应用的框架之一,其源码的深入理解对于开发者来说至关重要。这篇...

    spring4.0+spring MVC4.0+hibernate4.3全注解

    标题 "spring4.0+spring MVC4.0+hibernate4.3全注解" 涉及的是一个基于Java的Web开发技术栈,它整合了Spring 4.0、Spring MVC 4.0和Hibernate 4.3这三个流行框架。这个案例旨在展示如何在不使用XML配置的情况下,...

    Spring4.0+Hibernate4.0+Struts2.3整合案例

    Spring4.0+Hibernate4.0+Struts2.3整合案例:实现增删改查。 ===================== application.xml: &lt;?xml version="1.0" encoding="UTF-8"?&gt; xmlns="http://www.springframework.org/schema/beans" xmlns:xsi=...

    Spring4.0-API

    Spring4.0-API CHM格式,很难得的,希望能帮到大家!

Global site tag (gtag.js) - Google Analytics