JAX-WS и Guice 3 - PullRequest
       46

JAX-WS и Guice 3

3 голосов
/ 15 августа 2011

Есть ли какой-нибудь способ взять классы веб-сервисов SOAP, созданные с помощью JAX-WS, и внедрить их, скажем, с помощью транзакций Guice 3.0 (guice-persist) или даже просто инъекцией зависимостей?Пакет guiceyfruit предоставил аннотацию @GuiceManaged, которая сделала это возможным с Guice 2.0, но guiceyfruit (из моего тестирования) кажется несовместимым с Guice 3, и я не думаю, что проект более активен.

Возможно, потому что есть другой способ сделать это?Может быть, стандартным способом JSR?

Ответы [ 2 ]

1 голос
/ 10 ноября 2011

Я столкнулся с этой же проблемой некоторое время назад, посмотрел код Guicyfruit и решил извлечь то, что мне нужно.Это привело к трем классам.

Сначала нам понадобится аннотация, которую мы можем использовать для аннотирования конечной точки нашей веб-службы.

GuiceManaged.java

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.xml.ws.spi.WebServiceFeatureAnnotation;
import com.google.inject.Module;
import com.sun.xml.ws.api.server.InstanceResolverAnnotation;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@WebServiceFeatureAnnotation(id = GuiceManagedFeature.ID, bean = GuiceManagedFeature.class)
@InstanceResolverAnnotation(GuiceManagedInstanceResolver.class)
public @interface GuiceManaged {
    Class<? extends Module>[] modules();
}

Во-вторых, нам нужна GuiceManagedFeature, упомянутая в аннотации выше.

GuiceManagedFeature.java

import javax.xml.ws.WebServiceFeature;
import com.sun.xml.ws.api.FeatureConstructor;

public class GuiceManagedFeature extends WebServiceFeature {

    public static final String ID = "any.string.will.do.here";

    @FeatureConstructor
    public GuiceManagedFeature() {
        this.enabled = true;
    }

    @Override
    public String getID() {
        return ID;
    }
}

И в-третьих, мы создаем фактический преобразователь.

GuiceManagedInstanceResolver.java

import java.util.ArrayList;
import java.util.List;
import javax.xml.ws.WebServiceContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.sun.xml.ws.api.message.Packet;
import com.sun.xml.ws.api.server.WSEndpoint;
import com.sun.xml.ws.api.server.WSWebServiceContext;
import com.sun.xml.ws.server.AbstractMultiInstanceResolver;

public class GuiceManagedInstanceResolver<T> extends AbstractMultiInstanceResolver<T> {

    private static final Logger LOGGER = LoggerFactory.getLogger(GuiceManagedInstanceResolver.class);

    private static Injector injector;

    private transient WSWebServiceContext webServiceContext;

    public GuiceManagedInstanceResolver(final Class<T> clazz) {
        super(clazz);
    }

    @Override
    public T resolve(final Packet request) {
        final T instance = injector.getInstance(this.clazz);
        injector.injectMembers(instance);

        return instance;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public void start(final WSWebServiceContext wsWebServiceContext, final WSEndpoint endpoint) {
        super.start(wsWebServiceContext, endpoint);
        this.webServiceContext = wsWebServiceContext;

        synchronized (GuiceManagedInstanceResolver.class) {
            if (injector == null) {
                final List<Module> moduleInstances = new ArrayList<Module>();
                final Class<? extends Module>[] modules = this.clazz.getAnnotation(GuiceManaged.class).modules();

                for (final Class<? extends Module> moduleClass : modules) {
                    try {
                        moduleInstances.add(moduleClass.newInstance());
                    } catch (final InstantiationException exception) {
                        LOGGER.error("Could not instantiate guice module [{}]", moduleClass.getName());
                    } catch (final IllegalAccessException e) {
                        LOGGER.error("Could not instantiate guice module [{}]", moduleClass.getName());
                    }
                }

                moduleInstances.add(new AbstractModule() {
                    @Override
                    protected void configure() {
                        this.bind(WebServiceContext.class).toInstance(GuiceManagedInstanceResolver.this.webServiceContext);
                    }
                });

                injector = Guice.createInjector(moduleInstances);
            }
        }
    }
}

Приведенный выше пример использует SLF4J для ведения журнала, но, конечно, вы можете использовать все, что пожелаете.

1 голос
/ 15 августа 2011

В моих журналах есть ошибки, связанные с внутренними вызовами 2.0, которые больше не существуют в 3.0.Из кода GuiceManaged, на самом деле это всего лишь один вызов guicyfruit, поэтому я решил вырвать зависимость и поискать альтернативы.

В http://code.google.com/p/guice-recipes/ есть разветвление, которое может или можетне решить проблему, если использовать вместо guicyfruit.

Я использовал код http://code.google.com/p/google-guice/issues/detail?id=288#c69 и использовал его в качестве моего нового метода dispose () в GuiceManagedInstanceResolver.

У меня работает GuiceТеперь в моем коде есть уколы и аспекты, а в лог не выводятся отсутствующие методы и / или утечки памяти.

...