Главная » Spring » Создание конечных точек JAX-WS с поддержкой Spring

0

Выше в этой главе мы создавали удаленные службы с использо- ванием компонентов-экспортеров, входящих в состав фреймворка Spring. Эти компоненты волшебным образом преобразуют простые Java-объекты (POJO) в удаленные службы. Мы узнали, как соз- давать службы RMI с помощью RmiServiceExporter, службы Hessian с помощью HessianServiceExporter, службы Burlap с помощью Burlap- ServiceExporter и службы HTTP Invoker с помощью HttpInvokerServi- ceExporter. Теперь вы, вероятно, ожидаете, что я покажу, как создавать веб-службы с помощью компонента-экспортера, поддерживающего технологию JAX-WS.

В состав фреймворка Spring входит компонент-экспортер Simple- JaxWsServiceExporter, поддерживающий возможность создания веб- служб JAX-WS, и мы вскоре с ним познакомимся. Но прежде вы должны знать, что его применение подходит не во всех ситуациях. Вы увидите, что SimpleJaxWsServiceExporter требует, чтобы среда вре- мени выполнения JAX-WS поддерживала публикацию конечных точек для указанного адреса1. Среда времени выполнения JAX-WS, входящая в состав Sun JDK 1.6, соответствует этому требованию, но другие реализации JAX-WS, включая упоминаемую здесь, могут не соответствовать ему.

Если вам придется развертывать среду выполнения JAX-WS, не поддерживающую публикацию службы в указанном адресе, вы должны будете реализовать собственные конечные точки JAX-WS более обычным способом. Это означает, что жизненным циклом конечных точек будет управлять среда выполнения JAX-WS, а не Spring. Но это не означает, что их нельзя будет связать с компонен- тами в контексте приложения Spring.

Автоматическое связывание конечных точек JAX-WS в Spring

Модель программирования JAX-WS включает в себя использо- вание аннотаций для объявления классов и их методов операциями веб-службы. Класс, отмеченный аннотацией @WebService, считается

1 Точнее, это означает, что провайдер JAX-WS должен поставляться с соб- ственным HTTP-сервером для создания необходимой инфраструктуры публикации службы в требуемом адресе.

конечной точкой веб-службы, а его методы, отмеченные аннотацией

@WebMethod, – операциями.

Подобно любым другим объектам в достаточно крупном приложе- нии, конечная точка JAX-WS наверняка будет использовать в своей работе другие объекты. Это означает, что конечные точки JAX-WS с успехом могут пользоваться преимуществами приема внедрения зависимостей. Но поскольку жизненным циклом конечной точки управляет среда выполнения JAX-WS, а не Spring, кажется невоз- можным обеспечить внедрение компонентов, управляемых фрейм- ворком Spring, в экземпляры конечных точек, управляемых средой выполнения JAX-WS.

Секрет связывания конечных точек JAX-WS заключается в насле- довании ими класса SpringBeanAutowiringSupport. Если класс конечной точки будет наследовать класс SpringBeanAutowiringSupport, свойства этого класса можно пометить аннотацией @Autowired и тем самым обеспечить возможность внедрения зависимостей1. В листинге 11.2 представлен класс SpitterServiceEndpoint, демонстрирующий исполь- зование этого приема.

Листинг 11.2. Конечная точка JAX-WS, наследующая класс SpringBeanAutowiringSupport

package com.habuma.spitter.remoting.jaxws; import    java.util.List;

import javax.jws.WebMethod; import   javax.jws.WebService;

import  org.springframework.beans.factory.annotation.Autowired;

import     org.springframework.web.context.support.SpringBeanAutowiringSupport;

import  com.habuma.spitter.domain.Spitter; import   com.habuma.spitter.domain.Spittle;

import com.habuma.spitter.service.SpitterService;

1 Хотя в данном случае прием наследования класса SpringBeanAutowiring- Support используется, чтобы обеспечить возможность автоматического связывания для конечных точек JAX-WS, этот же прием с успехом может применяться к любым объектам, управление жизненным циклом кото- рых выполняется за пределами Spring. Единственное требование состоит в том, чтобы контекст приложения Spring и сторонняя среда выполнения находились в пределах одного и того же веб-приложения.

@WebService(serviceName="SpitterService") public class SpitterServiceEndpoint

extends SpringBeanAutowiringSupport {  // Включает поддержку

// автоматического связывания

@Autowired

SpitterService spitterService;                     // Для внедрения SpitterService

@WebMethod

public  void  addSpittle(Spittle  spittle)  { spitterService.saveSpittle(spittle);

}

@WebMethod

public  void  deleteSpittle(long  spittleId)  {

// Выполнение делегируется службе SpitterService spitterService.deleteSpittle(spittleId);

}

@WebMethod

public  List<Spittle>  getRecentSpittles(int  spittleCount)  {

// Выполнение делегируется службе SpitterService return         spitterService.getRecentSpittles(spittleCount);

}

@WebMethod

public   List<Spittle>   getSpittlesForSpitter(Spitter   spitter)   {

// Выполнение делегируется службе SpitterService return        spitterService.getSpittlesForSpitter(spitter);

}

}

Здесь свойство spitterService отмечено аннотацией @Autowired, чтобы показать, что в него автоматически должен внедряться ком- понент из контекста приложения Spring, которому конечная точка будет делегировать фактическое выполнение операций.

Экспортирование автономных конечных точек JAX-WS

Как уже говорилось, прием наследования класса SpringBeanAuto- wiringSupport  удобно  использовать  для  внедрения  зависимостей в свойства объектов, управление жизненным циклом которых вы- полняется за пределами Spring. Но в некоторых ситуациях в качест- ве конечной точки JAX-WS можно экспортировать и компонент, управляемый фреймворком Spring.

Компонент SimpleJaxWsServiceExporter, входящий в состав Spring, действует аналогично другим компонентам-экспортерам, обсуждав- шимся выше в этой главе, экспортируя компоненты Spring в виде конечных точек служб в среду выполнения JAX-WS. В отличие от других компонентов-экспортеров, SimpleJaxWsServiceExporter не требу- ет ссылки на экспортируемый компонент. Вместо этого он публику- ет все компоненты, отмеченные аннотациями JAX-WS, как службы JAX-WS.

Настройка компонента SimpleJaxWsServiceExporter может быть вы- полнена с помощью элемента <bean>, как показано ниже:

<bean  class=

"org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter"/>

Как видите, компонент SimpleJaxWsServiceExporter ничего не требу- ет для своей работы. При запуске он отыскивает в контексте при- ложения Spring компоненты с аннотацией @WebService. Обнаружив такой компонент, он экспортирует его как конечную точку JAX-WS с базовым адресом http://localhost:8080/.

В листинге 11.3 демонстрируется один из таких компонентов, об- наруживаемых  компонентом  SpitterServiceEndpoint.

Листинг 11.3. Компонент SimpleJaxWsServiceExporter превращает другие компоненты в конечные точки JAX-WS

package com.habuma.spitter.remoting.jaxws; import    java.util.List;

import javax.jws.WebMethod; import   javax.jws.WebService;

import  org.springframework.beans.factory.annotation.Autowired; import   org.springframework.stereotype.Component;

import  com.habuma.spitter.domain.Spitter; import   com.habuma.spitter.domain.Spittle;

import com.habuma.spitter.service.SpitterService;

@Component

@WebService(serviceName="SpitterService") public  class  SpitterServiceEndpoint  {

@Autowired

SpitterService spitterService;      // Для внедрения SpitterService

@WebMethod

public  void  addSpittle(Spittle  spittle)  {

// Выполнение делегируется службе SpitterService spitterService.saveSpittle(spittle);

}

@WebMethod

public  void  deleteSpittle(long  spittleId)  {

// Выполнение делегируется службе SpitterService spitterService.deleteSpittle(spittleId);

}

@WebMethod

public  List<Spittle>  getRecentSpittles(int  spittleCount)  {

// Выполнение делегируется службе SpitterService return         spitterService.getRecentSpittles(spittleCount);

}

@WebMethod

public   List<Spittle>   getSpittlesForSpitter(Spitter   spitter)   {

// Выполнение делегируется службе SpitterService return        spitterService.getSpittlesForSpitter(spitter);

}

}

Обратите внимание, что эта новая реализация SpitterService- Endpoint больше не наследует класс SpringBeanAutowiringSupport. Как полноценный компонент Spring, она использует механизм автома- тического связывания без наследования специального класса под- держки.

Поскольку базовым адресом для SimpleJaxWsServiceEndpoint по умолчанию является адрес http://localhost:8080/, а также потому, что SpitterServiceEndpoint отмечен аннотацией @WebService(serviceN ame="SpitterService"), совокупность этих двух компонентов дает в результате веб-службу, привязанную к URL http://localhost:8080/ SpitterService. Однако URL службы полностью находится под ва- шим контролем. То есть при желании можно указать любой дру- гой базовый адрес. Например, следующее определение компонента SimpleJaxWsServiceEndpoint публикует ту же самую конечную точку службы в URL http://localhost:8888/services/SpitterService.

<bean  class=

"org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter" p:baseAddress="http://localhost:8888/services/"/>

Несмотря на простоту настройки компонента SimpleJaxWsService- Endpoint, следует помнить, что он может использоваться, только ес- ли среда выполнения JAX-WS поддерживает публикацию конечных точек в произвольные адреса. Такой поддержкой обладает среда вы- полнения JAX-WS, входящая в состав Sun 1.6 JDK. Другие реализа- ции JAX-WS, как упоминаемая здесь JAX-WS 2.1, не поддерживают подобного способа публикации конечных точек и потому не могут использоваться совместно с SimpleJaxWsServiceEndpoint.

Источник:   Уоллс К., Spring в действии. – М.: ДМК Пресс, 2013. – 752 с.: ил.

По теме:

  • Комментарии