Встроенная интеграция CXF в Grails - PullRequest
0 голосов
/ 16 февраля 2012

Кто-нибудь знает, как интегрировать фреймворк cxf без использования плагина cxf? Я уже опубликовал простой сервис, но моя проблема заключается в том, чтобы внедрить существующий bean-компонент grails в бин cxf jaxws.

В applicationContext.xml я использую следующее определение

<jaxws:server id="jaxwsService" serviceClass="at.pdts.cxf.HelloWorld" address="/hello">
    <jaxws:serviceBean>
        <bean class="at.pdts.cxf.HelloWorldImpl">
            <property name="halloService"><ref bean="helloWorld"></ref></property>
        </bean>
    </jaxws:serviceBean>
  </jaxws:server>

Бин helloWorld является классом обслуживания Grails. Во время запуска я получаю следующее исключение.

Невозможно разрешить ссылку на bean-компонент helloWorld при настройке bean-компонента. свойство 'halloService'; вложенное исключение - org.springframework.beans.factory.NoSuchBeanDefinitionException: не определен бин с именем helloWorld

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="
            http://cxf.apache.org/jaxws
            http://cxf.apache.org/schemas/jaxws.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>


    <bean id="grailsApplication" class="org.codehaus.groovy.grails.commons.GrailsApplicationFactoryBean">
        <description>Grails application factory bean</description>
        <property name="grailsDescriptor" value="/WEB-INF/grails.xml" />
        <property name="grailsResourceLoader" ref="grailsResourceLoader" />
    </bean>

    <bean id="pluginManager" class="org.codehaus.groovy.grails.plugins.GrailsPluginManagerFactoryBean">
        <description>A bean that manages Grails plugins</description>
        <property name="grailsDescriptor" value="/WEB-INF/grails.xml" />
        <property name="application" ref="grailsApplication" />
    </bean>

    <bean id="grailsConfigurator" class="org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator">
        <constructor-arg>
            <ref bean="grailsApplication" />
        </constructor-arg>
        <property name="pluginManager" ref="pluginManager" />
    </bean>

    <bean id="grailsResourceLoader" class="org.codehaus.groovy.grails.commons.GrailsResourceLoaderFactoryBean">
        <property name="grailsResourceHolder" ref="grailsResourceHolder" />
    </bean>

    <bean id="grailsResourceHolder" scope="prototype" class="org.codehaus.groovy.grails.commons.spring.GrailsResourceHolder">
        <property name="resources">
              <value>classpath*:**/grails-app/**/*.groovy</value>
        </property>
    </bean>    

   <bean id="characterEncodingFilter"
      class="org.springframework.web.filter.CharacterEncodingFilter">
        <property name="encoding">
          <value>utf-8</value>
        </property>
   </bean>

    <jaxws:server id="jaxwsService" serviceClass="at.pdts.cxf.HelloWorld" address="/hello">
    <jaxws:serviceBean>
        <bean class="at.pdts.cxf.HelloWorldImpl">
            <property name="halloService"><ref bean="halloService"></ref></property>
        </bean>
    </jaxws:serviceBean>
  </jaxws:server>

</beans>    

HelloWorldImpl.groovy

package at.pdts.cxf

import javax.jws.WebService

@WebService(endpointInterface = "at.pdts.cxf.HelloWorld")
public class HelloWorldImpl implements HelloWorld {

    def halloService // inject HelloService. Initialize this bean via applicationContext.xml

    public String sayHi(String text) {
        return "hello " + halloService.scream(text)
    }
}

HelloService.groovy

class HalloService implements InitializingBean{

static transactional = false

String scream(String text) {
    text.toUpperCase()
}

// methods gets not called, so service bean is not initialized at the ws creation time
void afterPropertiesSet() {

   println "------> initializing bean HalloSerivce <--------
}

}

Похоже, что в момент инициализации jaxwsService бин службы helloWorld недоступен.

Ответы [ 2 ]

2 голосов
/ 22 февраля 2012

Это должно указывать на что-то:

<ref bean="helloWorld">

У вас есть что-то вроде этого:

<bean id="helloWorld" class="at.pdts.cxf.HalloServiceImpl" />

Эта ошибка означает, что Spring теперь может находить bean-компонент Spring с псевдонимом helloWorld.

Возможно, вам поможет публикация всего вашего spring.xml и кода Java в HelloWorldImpl.

РЕДАКТИРОВАТЬ: ваш конфиг подтверждает мою теорию.

<ref bean= говорит: «впрысни сюда что-нибудь еще». Но вы не определили этот bean-компонент, отсюда и исключение No Only Bean Definition. Кроме того, я смог заставить ваш код работать, создав собственную реализацию HalloService (HalloServiceImpl) с помощью специального метода scream, который возвращает пустую строку. Затем я добавил его в конфигурацию пружины: <bean id="helloWorld" class="at.pdts.cxf.HalloServiceImpl" />

РЕДАКТИРОВАТЬ # 2: еще один способ заставить его работать, исключив HalloService:

<jaxws:server id="jaxwsService" serviceClass="at.pdts.cxf.HelloWorld" address="/hello">
    <jaxws:serviceBean>
        <bean class="at.pdts.cxf.HelloWorldImpl" />
    </jaxws:serviceBean>
  </jaxws:server>

</beans> 

HelloWorldImpl.groovy

package at.pdts.cxf

import javax.jws.WebService

@WebService(endpointInterface = "at.pdts.cxf.HelloWorld")
public class HelloWorldImpl implements HelloWorld {


    public String sayHi(String text) {
        return "hello scream!" + text
    }
}

По сути, вы можете выбрать: предоставить Spring реализацию HalloService или не ссылаться на нее в Spring.xml.

РЕДАКТИРОВАТЬ # 3: Существует недоразумение относительно цели InitializingBean:

Из Javadoc:

InitializingBean Интерфейс для реализации bean-компонентами, которые должны реагировать, как только все их свойства были установлены BeanFactory: для Например, чтобы выполнить пользовательскую инициализацию или просто проверить, что все обязательные свойства были установлены.

Реализация InitializingBean просто означает, что будет вызван afterPropertiesSet (). Значение не означает, что Spring автоматически добавит этот bean-компонент в конфигурацию Spring. Вы все еще должны объявить bean-компонент в конфигурации Spring с помощью этой строки:

<bean id="halloService" class="at.pdts.cxf.HalloService" /> 
0 голосов
/ 24 февраля 2012

Я пропустил это в первый раз, когда прочитал ваш вопрос, но вы определяете свой компонент в applicationContext.xml.Когда я делал тестовый пример для вашего вопроса, я помещал свое определение компонента в grails-app/conf/spring/resources.xml.Попробуйте создать этот файл и вставить в него следующее:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:lang="http://www.springframework.org/schema/lang"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xsi:schemaLocation="
        http://cxf.apache.org/jaxws
        http://cxf.apache.org/schemas/jaxws.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

    <!--create the bean for the service, link to groovy service bean -->
    <jaxws:server id="jaxwsService" serviceClass="at.pdts.cxf.HelloWorld" address="/hello">
        <jaxws:serviceBean>
            <bean class="at.pdts.cxf.HelloWorldImpl">
                <property name="halloService" ref="halloService" />
            </bean>
        </jaxws:serviceBean>
    </jaxws:server>
</beans>

В качестве примечания вы можете найти больше информации об интеграции Grails и CXF здесь .

...