Использование Guice 3 с JAX-WS в Java 6 вне веб-контейнера - PullRequest
5 голосов
/ 07 октября 2011

У нас есть ситуация, когда мы используем инъекции на основе JSR-330 для настройки наших автономных приложений Java 6, что очень хорошо работает для получения параметров конфигурации на всех уровнях.

Мы также использовали JAX-Веб-сервисы WS довольно долгое время использовали первый автономный дистрибутив Metro с Java 5 внутри веб-контейнера, но в Java 6 мы просто используем класс Endpoint, чтобы получить меньшую площадь.

Так что теперь у меня естьСитуация, когда у меня

  • Автономное приложение Java 6 - без контейнера сервлетов (Jetty, Tomcat)
  • Инжектор Guice 3 настроен так, как мне нравится.
  • Endpoint, обрабатывающий мой @javax.jws.WebService аннотированный класс, который представляет мои методы как веб-сервисы.

Я бы хотел, чтобы методы веб-службы либо обрабатывали свои поля @Inject прозрачно, либо чтобы получить доступ к инжектору.Я могу взять его как статическое поле из основного метода, но я бы хотел более чистое решение.

Есть предложения?

(из JAX-WS и Guice 3 я понимаю, что модуль http://jax -ws-commons.java.net / guice / не работает с Guice3, и предложенный обходной путь является специфическим для Tomcat)

Будут ли здесь полезны аннотации JSR-250 @Resource?

Ответы [ 2 ]

5 голосов
/ 12 октября 2011

Я не уверен, что понял каждый вопрос.Это выглядит слишком легко для +500 щедрости.Пожалуйста, напишите код, если это не то, что вы ищете.

В любом случае, простое решение, которое создает веб-сервис с внедрением зависимостей:

final Module module = new HelloModule();
final Injector injector = Guice.createInjector(module);
final HelloService helloService = injector.getInstance(HelloService.class);

Endpoint.publish("http://localhost:8080/helloService", helloService);

Ниже более сложное решение с classpathсканирование ( Reflections ) на основе кода Маркуса Эрикссона из Интеграция JAX-WS Guice .Он публикует все классы, которые отмечены @GuiceManaged как веб-сервис с Endpoint.publish().

private void initGuicedWebservices(final String packageNamePrefix) 
        throws Exception {
    final Reflections reflections = new Reflections(packageNamePrefix);
    final Set<Class<?>> guiceManaged = 
        reflections.getTypesAnnotatedWith(GuiceManaged.class);
    for (final Class<?> clazz : guiceManaged) {
        doGuice(clazz);
    }
}

private void doGuice(final Class<?> clazz) throws Exception {
    final GuiceManaged guiceManagedAnnotation = 
        clazz.getAnnotation(GuiceManaged.class);

    final Injector injector = createInjector(guiceManagedAnnotation);

    final Object serviceObject = clazz.newInstance();
    injector.injectMembers(serviceObject);

    final String address = guiceManagedAnnotation.address();

    Endpoint.publish(address, serviceObject);
}

private Injector createInjector(final GuiceManaged guiceManagedAnnotation) 
        throws Exception {
    final Class<? extends Module>[] moduleClasses = 
        guiceManagedAnnotation.module();

    final List<Module> moduleInstances = new ArrayList<Module>();
    for (final Class<? extends Module> moduleClass : moduleClasses) {
        moduleInstances.add(moduleClass.newInstance());
    }

    return Guice.createInjector(moduleInstances);
}

Аннотация GuiceManaged:

@Retention(RUNTIME)
@Target(TYPE)
@Documented
public @interface GuiceManaged {
    public Class<? extends Module>[] module();
    public String address();
}

И фрагмент HelloServiceImpl:

@GuiceManaged(module = HelloModule.class, 
    address = "http://localhost:8080/helloService")
@WebService
public class HelloServiceImpl implements HelloService {

    @Inject // bound in HelloModule
    public GreetingsService greetingsService;

    @Override
    @WebMethod
    public String sayHello(final String name) {
        return greetingsService.sayHello(name);
    }
}
0 голосов
/ 11 октября 2011

вам нужно использовать точку расширения AbstractMultiInstanceResolver.

создать аннотацию GuiceManaged;

@Retention(RUNTIME)
@Target(TYPE)
@Documented
@WebServiceFeatureAnnotation(id=GuiceManagedFeature.ID, bean=GuiceManagedFeature.class)
@InstanceResolverAnnotation(GuiceManagedInstanceResolver.class)
public @interface GuiceManaged {
}

реализует GuiceManagedFeature, который WebServiceFeature:

public class GuiceManagedFeature extends WebServiceFeature {
    public static final String ID="FEATURE_GuiceManaged";

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

    public String getID() {
        return ID;
    }
}

Реализация InstanceResolver путем расширения AbstractMultiInstanceResolver

public class GuiceManagedInstanceResolver extends AbstractMultiInstanceResolver {
    private T instance=null;
    public GuiceManagedInstanceResolver(@NotNull Class clazz)
    {
        super(clazz);
    }
    public T resolve(@NotNull Packet request) {
        if(instance==null)
        {
            instance=create();
            Injector injector= Guice.createInjector(new WebServiceModule());
            injector.injectMembers(instance);
        }
        return instance;
    }
}

Теперь аннотируйте свою службу с помощью @GuiceManaged и используйте @Inject для DI уровня метода в вашем бизнес-методе.

...