2017-02-03 2 views
0

У меня есть интеграция, настроенная с использованием Spring с использованием Apache Axis в качестве клиента SOAP.Запросы и ответы клиента Axis с использованием Spring bean

Я могу настроить client-config.wsdd для настройки обработчика как класса, который находится вне контекста весны. То, что я хотел бы сделать, - настроить обработчик так, чтобы он находился в контексте весны. Это возможно?

Вот мой текущий client-config.wsdd

<?xml version="1.0" encoding="UTF-8"?> 
<deployment name="defaultClientConfig" 
      xmlns="http://xml.apache.org/axis/wsdd/" 
      xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> 

    <handler name="log" type="java:xxx.xxx.handler.SOAPLogHandler"> 
    </handler> 

    <globalConfiguration> 
     <parameter name="disablePrettyXML" value="false"/> 
     <requestFlow> 
      <handler type="log"/> 
     </requestFlow> 
     <responseFlow> 
      <handler type="log"/> 
     </responseFlow> 
    </globalConfiguration> 

    <transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/> 
</deployment> 

Я также сервис зарегистрирован весной:

<bean id="wsYPSoap" class="xxx.xxx.core.ws.WsYPSoapProxy"> 
    <constructor-arg value="${xxx.service.url}" /> 
</bean> 

ответ

0

Я искал способ использования Spring боб непосредственно в качестве обработчика для клиента оси и точно для целей регистрации данных запроса/ответа.

Кажется, что в настоящее время нет простого и простого способа сделать это.

Существует, однако, способ сделать это, обратившись к компоненту Spring из обработчика оси через корневой контекст приложения. Есть несколько вопросов здесь:

  • обработчиков оси инстанцируется, когда они необходимы как простые классы (не бобы)

  • экземпляры обработчика не могут рассчитывать на существование любого сервлета (или, т.е. Faces) контекст в момент их метод invoke() называется

из-за этого, вы должны поместить Spring боб в контексте корневого приложения. Проблема в том, что вы не можете получить доступ к контексту приложения обычным способом (то есть через ServletContext от FacesContext). Обходным путем для этого является создание вашего собственного компонента ApplicationContextAware, который сохранит ссылку на корневой контекст приложения при запуске приложения для использования в обработчике Axis.

Minimal ApplicationContextAware боб Пример реализации:

public class ApplicationContextProvider implements ApplicationContextAware { 
    private static ApplicationContext rootAppContext; 

    @Override 
    public void setApplicationContext(ApplicationContext ctx) throws BeansException { 
     rootAppContext = ctx; 
    } 

    public static ApplicationContext getApplicationContext() { 
     return rootAppContext; 
    } 
} 

и application-context.xml объявить боб:

<bean id="appContextProvider" lazy-init="false" class="package.where.the.class.is.ApplicationContextProvider" /> 

Обратите внимание на lazy-init="false" в декларации, это важно. Поскольку этот компонент не упоминается (или автоматически подключен) в любом месте, Spring не будет создавать экземпляр его когда-либо, потому что Spring использует ленивую стратегию для создания bean-компонентов. Установка lazy-init в false позволяет убедиться, что компонент создан при запуске приложения.

При условии, что у вас есть DB протоколирования боб (реализованный DBLogBean класс) правильно установлен и загружен/создатель Spring, вы можете получить доступ к нему в обработчике оси, т.е. как это:

ApplicationContext ctx = ApplicationContextProvider.getApplicationContext(); 
if (ctx != null) { 
    DBLogBean bean = (DBLogBean) ctx.getBean("yourDBLogBeanId"); 
    if(bean != null) { 
     bean.doLogOrSomething(); 
    } 
} 

Убедитесь, что вы проверьте, ApplicationContextProvider.getApplicationContext() возвращает null или нет, прежде чем извлекать БД из контекста. Обратите внимание, что вы также должны проверить, возвращается ли ctx.getBean()null или нет.

Если это не вариант (то есть по какой-то причине, вы должны иметь боб DB всякий раз, когда обработчик оси называется), то вы должны убедиться, что обработчик оси только когда-либо называется после созданияApplicationContextProvider боб. Эта тема, однако, выходит за рамки здесь;)

Примечания: Создание бобов с помощью lazy-init="false" является не предпочтительного способа создания экземпляров боба. Бобы должны быть с автоматической проводкой/ссылки других фасолей/кода и оставлены на весну для управления их жизненным циклом. Например, один недостаток форсирования создания бина при запуске - вы не можете быть уверены, в какой момент они были созданы и станут доступными, если вы не предпримете дополнительные шаги для его обработки (или убедитесь, что на них ссылается другой код но тогда зачем использовать lazy-init="false" в первую очередь?).

Смежные вопросы