Spring DI applicationContext.xml, как именно используется xsi:schemaLocation?

Примечание: упомянутый мной тестовый проект можно скачать с:

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

.. и беги с "муравейником".

Я "понимаю", что имена пространств имен XML просто используются в качестве непрозрачных идентификаторов и не предназначены для использования в качестве URI ( википедия). Я также "понимаю", что расположения схемы XML предназначены для предоставления подсказок относительно фактического расположения документов схемы и, будучи подсказками, не используются на практике ( w3.org). Имея это в виду, я экспериментировал с простым приложением Spring DI (используемым в простом параметре J2SE), изменяя applicationContext.xml. Вот начальная версия:

<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}"/>                          

Когда я выполнил 'sudo ifconfig eth0 down', проект отлично работал, что согласуется со временем выполнения, не беспокоясь о получении чего-либо из schemaLocations. Однако, когда я исказил schemaLocations, добавив простое подчеркивание ко второму URL в каждой паре, я получил следующую жалобу:

 [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)

Кажется, это говорит о том, что среда выполнения Spring DI использует второй URL в каждой паре в xsi:schemaLocation как некоторый идентификатор (жестко закодированный в его логике, поскольку нет доступа к сети). Поэтому я предполагаю, что среда выполнения Spring DI использует два вида идентификаторов для каждого пространства имен: идентификатор xmlns для уникальной идентификации пространства имен (используется как непрозрачная строка) и идентификатор schemaLocation для уникальной идентификации версии схемы для этого пространства имен (снова используется как непрозрачная строка). Т.е. schemaLocation фактически используется (искаженным образом? Поскольку это не похоже на намерение документов w3c) для создания версии пространства имен. Более того, в таком случае почему среда выполнения Spring DI не жалуется на отсутствие расположения схемы для пространства имен "p". Правильна ли моя ментальная модель?

1 ответ

Решение

Вот что происходит:

  • Схема XML позволяет вам определять псевдонимы (короткие имена) для пространств имен XML. Технически все пространства имен идентифицируются полным URI, но это было бы очень громоздко - поэтому вы можете использовать короткие псевдонимы, такие как context а также p, Существует также пространство имен по умолчанию, обозначенное как xmlns атрибут

  • По умолчанию анализаторы XML предполагают, что URI пространства имен также является URL-адресом файла XSD. Это часто имеет место, но не требуется спецификацией. Так же работает XML-парсер в Spring, если вы не предоставите schemaLocation приписывать.

  • schemaLocation используется для сопоставления URI пространства имен с физическим местоположением файла XSD (URL). Он используется, когда пространство имен схемы не указывает на действительный URL-адрес XSD (см. MSDN наschemaLocation).

  • И последнее, но не менее важное: Spring добавляет еще один слой, который транслирует URL-адреса Интернета в локальные файлы на CLASSPATH. Таким образом, ваше приложение может запуститься без подключения к Интернету (или когда сайт springframework.org не работает).

Если вы будете искать в ваших библиотеках проекта, вы найдете несколько файлов с именем spring.schemas, Эти файлы содержат строки, аналогичные приведенным ниже (извлечение из файла, найденного в spring-context.jarЯ добавил расклад):

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
Другие вопросы по тегам