Статьи

Пользовательские пространства имен Spring

Пользовательские пространства имен Spring предоставляют хороший способ упростить xml-файлы, используемые для описания определений компонентов в контексте приложения Spring. Это довольно старая концепция, впервые появившаяся в Spring 2.0, но заслуживающая рассмотрения время от времени.

Рассмотрим случай, когда нужно сконфигурировать часть компонентов для приложения Spring MVC без пользовательских пространств имен — это обычно выглядит так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<bean name="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
 <property name="webBindingInitializer">
  <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
   <property name="conversionService" ref="conversionService"></property>
   <property name="validator">
    <bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
   </property>
  </bean>
 </property>
 <property name="messageConverters">
  <list>
   <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"></bean>
   <bean class="org.springframework.http.converter.StringHttpMessageConverter"></bean>
   <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"></bean>
   <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"></bean>
   <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"></bean>
   <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"></bean>
   <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
  </list>
 </property>
</bean>
 
<bean name="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
 <property name="useSuffixPatternMatch" value="false"></property>
</bean>

Здесь он настраивает два bean-компонента — handlerAdapter для обработки потока контроллера MVC и handlerMapping для сохранения соответствия между URI запроса и методами Controller для обработки запросов.

Та же конфигурация становится очень лаконичной с настраиваемым пространством имен, «http://www.springframework.org/schema/mvc» обычно с префиксом namspace «mvc»:

1
2
<mvc:annotation-driven conversion-service="conversionService">
</mvc:annotation-driven>

По сути, это является преимуществом использования пользовательского пространства имен — очень краткого способа описания определений bean-компонента Spring.

Итак, как работает пользовательское пространство имен:

Этот раздел в справочном документе Spring описывает его гораздо лучше, чем я — http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/extensible-xml.html#extensible-xml -схема Подводя итог, пользовательское пространство имен состоит из 4 частей:

  • схема, которая описывает структуру пользовательского пространства имен — имена тегов, атрибуты, дочерние теги и т. д.
  • NamespaceHandler — который создает определение компонента для элементов xml. Однако обычно лучшим механизмом, предлагаемым в документе Spring, является расширение NameSpaceHandlerSupport и регистрация серии BeanDefinitionParser (s) для различных элементов xml, поддерживаемых пользовательским пространством имен (скажем, управляемым аннотациями, элементами-перехватчиками пространства имен mvc).
  • BeanDefinitionParser — создайте определение bean-компонента для конкретного элемента — здесь строка, подобная <mvc: annotation-driven />, будет расширена до более широких определений bean-компонентов с фактическими именами классов bean-компонентов.
  • Регистрация схемы, NamespaceHandler — это для Spring, чтобы найти схему для пользовательских пространств имен и найти NamespaceHandler, который будет обрабатывать пользовательское пространство имен. Регистрация схемы выполняется с помощью файла META-INF / spring.schemas , это отличный способ для Spring найти схему в classpath, а не загружать схему через Интернет. NamespaceHandler дополнительно указывается с использованием файла META-INF / spring.handlers и содержит имя NamespaceHandler, которое будет обрабатывать пользовательское пространство имен, например, для. из весенней документации —
1
http\://www.mycompany.com/schema/myns=org.springframework.samples.xml.MyNamespaceHandler

Связывая это вместе

Эта информация о том, как внутреннее пространство Пользовательского пространства работает, может быть эффективно использована для понимания поведения некоторых пользовательских тегов пространства имен. Рассмотрим тег для загрузки файла свойств:

1
<context:property-placeholder location="classpath*:META-INF/spring/database.properties"/>

Итак, чтобы выяснить, как элемент property-placeholder работает внутри, сначала найдите файл spring.handlers. Поскольку свойство-заполнитель находится в пространстве имен контекста, файл spring.handlers будет присутствовать в файле spring-context.jar.

и файл указывает, что NamespaceHandler является org.springframework.context.config.ContextNamespaceHandler

ContextNameSpaceHandler регистрирует синтаксический анализатор BeanDefinition с именем org.springframework.context.config.PropertyPlaceholderBeanDefinitionParser. Этот BeanDefinitionParser создает определение компонента с именем класса « PropertyPlaceholderConfigurer », и поэтому по сути мы могли бы заменить:
1
<context:property-placeholder location="classpath*:META-INF/spring/database.properties" local-override="true" properties-ref="localProperties"/>

с потерей лаконичности в процессе —

1
2
3
4
5
6
7
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
 <property name="location" value="classpath*:META-INF/spring/database.properties"></property>
 <property name="localOverride" value="true"></property>
 <property name="properties">
  <ref bean="localProperties"/>
 </property>
</bean>

Это, однако, обеспечивает хороший способ понять некоторые нюансы в том, как Spring обрабатывает вещи, лежащие в основе пользовательского пространства имен.

Ссылка: Spring Custom Namespaces от нашего партнера JCG Биджу Кунджуммен в блоге all and sundry.