2012-05-26 13 views
6

Nota: el proyecto de prueba que estoy mencionando puede ser descargado con:Spring DI applicationContext.xml ¿cómo se usa exactamente xsi: schemaLocation?

git clone https://github.com/mperdikeas/so-spring-di-appcontext-schemalocation.git

.. y correr con 'ant run'.

'Entiendo' que los nombres del espacio de nombres XML solo se utilizan como identificadores opacos y no se deben usar como URI (wikipedia). También 'entiendo' que las ubicaciones de esquema XML están destinadas a proporcionar pistas sobre la ubicación real de los documentos de esquema y, como consejos, no se usan en la práctica (w3.org). Con esto en mente, he estado experimentando con una aplicación Spring DI simple (utilizada en una configuración J2SE simple) al modificar el applicationContext.xml. Aquí está la versión de partida:

<beans xmlns    = "http://www.springframework.org/schema/beans"            
     xmlns:xsi   = "http://www.w3.org/2001/XMLSchema-instance"            
     xmlns:context  = "http://www.springframework.org/schema/context"           
     xmlns:p   = "http://www.springframework.org/schema/p"             
     xsi:schemaLocation="http://www.springframework.org/schema/beans            
          http://www.springframework.org/schema/beans/spring-beans-2.5.xsd       
          http://www.springframework.org/schema/context            
         http://www.springframework.org/schema/context/spring-context-2.5.xsd">      

<context:component-scan base-package="atm"/>                  
<context:property-placeholder location="classpath:META-INF/spring/atm.properties"/>         

<bean id="soapTransport_" class="atm.SoapATMTransport" p:retries="${transport.retries}"/>       

Cuando hice un proyecto 'sudo ifconfig eth0 down' corrió perfectamente cual es consistente con el tiempo de ejecución sin molestarse en busca de cualquier cosa, desde los schemaLocations. Sin embargo, cuando me ha mezclado los schemaLocations añadiendo un subrayado sencillo de la segunda URL en cada par recibí la siguiente denuncia:

[java] org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 10 in XML document from class path resource [META-INF/spring/applicationContext.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 10; columnNumber: 100; cvc-elt.1: Cannot find the declaration of element 'beans'. 
[java]  at org.apache.tools.ant.taskdefs.ExecuteJava.execute(ExecuteJava.java:194) 
[java]  at org.apache.tools.ant.taskdefs.Java.run(Java.java:771) 
[java]  at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:221) 
[java]  at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:135) 
[java]  at org.apache.tools.ant.taskdefs.Java.execute(Java.java:108) 
[java]  at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291) 
[java]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
[java]  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
[java]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
[java]  at java.lang.reflect.Method.invoke(Method.java:601) 
[java]  at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106) 
[java]  at org.apache.tools.ant.Task.perform(Task.java:348) 
[java]  at org.apache.tools.ant.Target.execute(Target.java:390) 
[java]  at org.apache.tools.ant.Target.performTasks(Target.java:411) 
[java]  at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399) 
[java]  at org.apache.tools.ant.Project.executeTarget(Project.java:1368) 
[java]  at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41) 
[java]  at org.apache.tools.ant.Project.executeTargets(Project.java:1251) 
[java]  at org.apache.tools.ant.Main.runBuild(Main.java:809) 
[java]  at org.apache.tools.ant.Main.startAnt(Main.java:217) 
[java]  at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280) 
[java]  at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109) 

lo que parece sugerir que la primavera DI tiempo de ejecución utiliza el segundo URL en cada par en el xsi : schemaLocation como algún tipo de identificador (codificado en su lógica ya que no hay acceso a la red). Así que mi hipótesis sería que el tiempo de ejecución DI primavera utiliza dos tipos de identificadores para cada espacio de nombres: el identificador xmlns para identificar de forma única el espacio de nombres (utilizado como una cadena opaca) y el identificador schemaLocation para identificar de forma exclusiva la versión de esquema para ese espacio de nombres (usado nuevamente como una cadena opaca). Es decir. el schemaLocation se usa de hecho (de forma contorsionada, ya que no parece ser la intención de los documentos w3c) para versionar el espacio de nombres. Además, en tal caso, ¿por qué el tiempo de ejecución de Spring DI no se queja de la falta de un schemaLocation para el espacio de nombres "p". ¿Mi modelo mental es correcto?

Respuesta

10

Esto es lo que sucede:

  • esquema XML permite definir alias (nombres cortos) a espacios de nombres XML. Técnicamente, todos los espacios de nombres se identifican mediante un URI completo, pero eso sería muy engorroso, por lo que puede usar alias cortos como context y p. También hay un espacio de nombres predeterminado denotado por xmlns atributo

  • De forma predeterminada, los analizadores XML asumen que el URI del espacio de nombres también es una ubicación de URL del archivo XSD. Este es a menudo el caso, pero no es requerido por la especificación. Así es también cómo funciona el analizador XML en Spring si no proporciona el atributo schemaLocation.

  • schemaLocation se utiliza para asignar desde URI de espacio de nombres a la ubicación física del archivo XSD (URL). Se utiliza cuando el espacio de nombres de esquema no marca a URL de XSD válida (consulte MSDN on schemaLocation).

  • Por último pero no menos importante, Spring agrega otra capa que traduce URL de Internet a archivos locales en CLASSPATH.De esta forma, su aplicación puede comenzar sin conexión a Internet (o cuando el sitio de springframework.org está inactivo).

Si busca en las bibliotecas de sus proyectos, encontrará varios archivos llamados spring.schemas. Estos archivos contienen líneas similares a continuación (extracto del archivo encontrado en spring-context.jar, añadí alineación):

http\://www.springframework.org/schema/context/spring-context.xsd= org/springframework/context/config/spring-context-3.1.xsd 
http\://www.springframework.org/schema/jee/spring-jee.xsd=   org/springframework/ejb/config/spring-jee-3.1.xsd 
http\://www.springframework.org/schema/lang/spring-lang.xsd=  org/springframework/scripting/config/spring-lang-3.1.xsd 
http\://www.springframework.org/schema/cache/spring-cache.xsd=  org/springframework/cache/config/spring-cache-3.1.xsd 
+0

Gracias, que es un modelo claro. Dos preguntas adicionales si puedo: [1] en las bibliotecas de mi proyecto solo hay un archivo spring.schemas (en spring.jar) y no parece contener un mapeo como el que describe para el 'xsi' y 'p' namespaces (aunque podría encontrar el 'contexto' y las asignaciones de espacio de nombres raíz), [2] ¿dónde está documentada esa cosa de mapeo? –

+0

@MenelaosPerdikeas: desafortunadamente no sé las respuestas a ambos [1] y [2]. –

Cuestiones relacionadas