2016-08-17 2 views
0

Прежде всего, это не упрямый вопрос, и я прочитал большинство связанных вопросов в SO. Я ищу совет, если ниже реализовано решение - правильный подход/метод.Зависимость Инъекция с использованием CDI с Джерси с/без привязки к абстрактному

Я прочитал много учебников о том, как реализовать DI в jersey-based веб-приложение, и большинство из них рекомендуют его должно создать в WEB-INF/* с beans.xml для того, чтобы позволить CDI, но мне интересно, если с помощью Джерси AbstractBinder достичь того же результата ?

У меня есть майка-веб-приложение, которое имеет следующее web.xml

<servlet> 
    <servlet-name>Test Jersey</servlet-name> 
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> 

    <init-param> 
     <param-name>javax.ws.rs.Application</param-name> 
     <param-value>com.test.config.AppConfig</param-value> 
    </init-param> 

И com.test.config.AppConfig, как следовать

public class AppConfig extends ResourceConfig { 
    public AppConfig() { 
     AbstractBinder binder = new AbstractBinder() { 
      @Override 
      protected void configure() {      
       bind(Impl.class).to(Interface.class).in(Singleton.class); 
      } 
     }; 
     register(binder); 
     register(MultiPartFeature.class); 
     packages("..."); //packages 
    } 
} 

, а затем я аннотирования интерфейсов и реализация получает впрыскивается

@Inject 
private SomeInterface someInterface; 

Над работами просто отлично. Независимо от того, что я хочу быть введенным, я включаю его в binder, а затем указываю injection point и вводит его.

Там не находится в WEB-INF/ каталоге нет beans.xml и мне интересно, если с помощью AbstractBinder внутри AppConfig, что расширяет ResourceConfig устранить необходимость объявлять beans.xml?

Добавление beans.xml, вероятно, позволит сканировать классы, которые проложили бы путь для DI, когда мы аннотируем классы с помощью @Component или @ManagedBean.

Несмотря на это, я был бы рад услышать ваши отзывы/посоветуйте/предложения/рекомендации о том, чтобы

  1. палочке с существующим решением (как показано выше) для DI в Джерси, потому что ....?
  2. Переключиться на классы аннотации (которые необходимо ввести) и использовать аннотацию-открытие beans.xml, потому что ...?
  3. Джерси использует HK2 по умолчанию, стоит ли использовать другой контейнер DI или HK2 достаточно хорош?
  4. Каково ваше мнение о Spring Jack Джерси по сравнению с JavaEE 6 CDI только для целей DI?

Есть много руководств, в которых указано, что CDI не поддерживается Tomcat? но работал выше, используя AbstractBinder, и я предполагаю его, потому что я программно связываю? Любые комментарии.

ответ

0

У меня нет четких ответов, и, возможно, их не существует. Не в последнюю очередь потому, что Weld SE support was introduced in version 2.15 of Jersey и это, конечно, не без причины. Но я хотел бы дать ему попробовать:

  1. Показанная решение отлично подходит для несложных проектов структур, но объявляя каждый связыванием не может быть лучшим решением
  2. Вам не нужно использовать beans.xml работы.Аннотации и автоматическое связывание прекрасно работают с некоторыми дополнительными усилиями (см. Ниже)
  3. Я не уверен в этом, но сказал бы, что Weld выглядит более продвинутым. И, конечно же, вы могли бы немного смешать CDI. не
  4. (нет ответа здесь)

Вот пример, который я думаю, что может быть интересно:

зависимости (Maven):

<dependency> 
    <groupId>org.glassfish.hk2</groupId> 
    <artifactId>hk2-metadata-generator</artifactId> 
    <version>2.5.0-b05</version> <!-- HK2 version int. used by Jersey 2.23.2 --> 
</dependency> 
<dependency> 
    <groupId>org.glassfish.jersey.containers</groupId> 
    <artifactId>jersey-container-servlet</artifactId> 
</dependency> 

прослушиватель событий приложений:

import org.glassfish.hk2.api.*; 
import org.glassfish.jersey.server.*; 

@Provider 
public class ApplicationListener implements ApplicationEventListener { 

    @Inject ServiceLocator serviceLocator; 

    @Override 
    public void onEvent(ApplicationEvent event) { 
     switch (event.getType()) { 
     case INITIALIZATION_FINISHED: 
      onInitFinished(); 
      break; 
     case DESTROY_FINISHED: 
     case INITIALIZATION_APP_FINISHED: 
     case INITIALIZATION_START: 
     case RELOAD_FINISHED: 
     default: 
      break; 
     } 
    } 

    @Override 
    public RequestEventListener onRequest(RequestEvent requestEvent) { return null; } 

    public void onInitFinished() { 
     populate(serviceLocator); 
    } 

    private void populate(ServiceLocator serviceLocator) { 
     DynamicConfigurationService dcs = serviceLocator.getService(DynamicConfigurationService.class); 
     Populator populator = dcs.getPopulator(); 
     try { 
      populator.populate(); 
     } catch (IOException | MultiException e) { 
      throw new MultiException(e); 
     } 
    } 
} 

Контракт:

import org.jvnet.hk2.annotations.Contract; 

@Contract 
public interface ExampleService { 
    void executeSomething(); 
} 

Один или несколько услуг:

import javax.inject.Named; 
import org.jvnet.hk2.annotations.Service; 

@Service 
@Named("bar") 
public class BarService implements ExampleService { 

    @Override 
    public void executeSomething() { /* doBar */ } 

} 

Использование:

@Path("/") 
public class TestResource { 

    // either ... 
    @Inject 
    @Named("bar") 
    private ExampleService bar; 

    // or ... 
    @Inject 
    private IterableProvider<ExampleService> services; 

} 

Просто вариант, чтобы избавиться от beans.xml (который я никогда не использовал или видел) или декларации в пределах ResourceConfig, но он может найти заинтересованные стороны :)

Addi Похоже, Jersey 3.0 отправляется ^^

Имейте славный день!

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