2014-01-08 3 views
8

Я использую Джерси 2 и весну, и я пытаюсь инициализировать приложение на основе Джерси (т. Е. Класс, полученный из ResourceConfig), с параметрами из контекста Spring.Как инициализировать приложение-приложение (ResourceConfig) с весной?

Справочная информация. У меня есть одно приложение-Джерси, которое я создаю (например, одна WAR), и я развертываю его через кластер серверов с различными конфигурациями Spring на разных серверах для включения или отключения различных частей сервера, например. некоторые из серверов имеют /search ресурсы включены, и т.д. Это было очень легко в Джерси 1.0: Я просто положить,

<context:component-scan base-package="com.mycompany.resources.search"/> 

в Спринг конфигурации, чтобы иметь Джерси отсканировать этот конкретный пакет и позволит поставщикам ресурсов JAX-RS в этом.

Сейчас в Джерси 2.0 Весна <context:component-scan ... /> не работает, поэтому ресурсы должны быть программно зарегистрированы в классе запуска, полученном из ResourceConfig:

public class MyApplication extends ResourceConfig { 

    public MyApplication() { 
     packages("com.mycompany.resources.search"); 
    } 
} 

До сих пор так хорошо, но мне нужно условно сканируйте этот пакет, и я не могу понять, как получить конфигурацию Spring в классе MyApplication. Я думал, что инъекции конструктор может работать:

public class MyApplication extends ResourceConfig { 

    @Autowired 
    public MyApplication(@Qualifier("my-config") MyConfiguration myConfiguration) { 
     if (myConfiguration.isEnabled()) { 
      packages("com.mycompany.resources.search"); 
     } 
    } 
} 

Однако HK2 жалуется, что не может найти конструктор по умолчанию для использования ... так что это указывает мне, что DI находится в игре, в строительстве этого класса, но что DI не использует Spring.

Аналогично, используя жизненный цикл весна фасоль не работает:

public class MyApplication extends ResourceConfig implements InitializingBean { 

    @Autowired 
    private MyConfiguration myConfiguration; 

    public MyApplication() { 
    } 

    @Override 
    public void afterPropertiesSet() throws Exception { 
     if (myConfiguration.isEnabled()) { 
      packages("com.mycompany.resources.search"); 
     } 
    } 
} 

(. Метод afterPropertiesSet не называется)

Так что теперь я застрял: есть ли способ для настройки объекта приложения Jersey ResourceConfig с использованием Spring?

UPDATE:

я принял @ ответ JohnR в поле ниже, но я буду также включать в свое окончательное решение, которое я думаю, это немного чище. @ Ответ JohnR состоял в том, чтобы объект инициализировался дважды: сначала весной, а затем Джерси/HK2. Когда Spring инициализирует объект, который вы кешируете зависимости в статическом члене, а затем, когда Jersey/HK2 инициализирует его позже, вы можете получить зависимости.

я в конечном итоге делает это:

public class MyApplication extends ResourceConfig { 

    public MyApplication() { 
     ApplicationContext rootCtx = ContextLoader.getCurrentWebApplicationContext(); 
     MyConfiguration myConfiguration = rootCtx.getBean(MyConfiguration.class); 

     if (myConfiguration.isEnabled()) { 
      packages("com.mycompany.resources.whatever"); 
     } 
    } 
} 

Вместо того, объект инициализируется дважды, мы позволяем Джерси/HK2 инициализировать его, но затем мы получаем зависимости от Spring.

Оба решения уязвимы для синхронизации: оба они предполагают, что весна инициализирована до Джерси/HK2.

+0

Я столкнулся с аналогичными проблемами с Джерси 2 + Весной. В конце концов, я закончил свою собственную интеграцию. [Помогает ли мой ответ на этот вопрос] (http://stackoverflow.com/questions/20506644/jersey-spring3-instantiating-spring-managed-bean-null)? –

+0

Это отличный ответ. Очень жаль, что вам пришлось перевернуть собственный мост Джерси/Весна. К сожалению, мой опыт был схож: много потраченного впустую времени с Джерси 2 и весной. Я сейчас работаю, но у моста с джерси2-весной, кажется, есть узкий «счастливый путь», и многие ловушки, если вы блуждаете. Мой совет кому-нибудь еще, приступая к Джерси 2 и Весне: следуйте [пример приложения] (https://github.com/jersey/jersey/tree/master/examples/helloworld-spring-webapp) и не пытайтесь делать что-то другое, потому что это не сработает. –

ответ

0

Итак, теперь я застрял: есть ли способ настроить Джерси Объект приложения ResourceConfig с использованием Spring?

Я не думаю, что вы можете настроить Джерси, чтобы получить ResourceConfig из Spring как управляемый Spring компонент. Это немного хаки, но вы можете сделать что-то вроде этого. Обратите внимание, что вы будете в конечном итоге с двумя экземпляра вашего ResourceConfig: один управляемый весной и другой на Джерси:

public class MyApplication extends ResourceConfig { 

    // static, available to all instances 
    private static MyConfiguration myConfiguration; 

    public MyApplication() { 
     // when Spring creates the first instance of MyApplication, myConfiguration 
     // will be null because the setter wasn't called yet 
     if (myConfiguration != null) 
     { 
      // second instance created by jersey... Spring will have autowired 
      // the first instance, and myConfiguration is static 
      if (myConfiguration.isEnabled()) 
       packages("com.mycompany.resources.search"); 
     } 
    } 

    @Autowired 
    public void setMyConfiguration(MyConfiguration config) 
    { 
     // instance level setter saves to a static variable to make it available for 
     // future instances (i.e. the one created by jersey) 
     MyApplication.myConfiguration = config; 
    } 
} 

Опять же, это довольно хаком. Вы хотите, чтобы Spring была инициализирована до Джерси и внимательно изучала любые проблемы с потоками, которые могли возникнуть во время инициализации.

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