2013-05-10 4 views
1

У меня есть приложение без клиента, которое я хочу запустить. У него не будет клиентов, но он будет делать HTTP-вызовы и действовать как клиент для других сервисов. Он будет работать, пожалуй, несколько часов или дней (но это не потребует периодических прогонов - всего один выстрел).Как написать main() с использованием CDI в Java EE?

Я хочу запустить его в контейнере Java EE 7 из-за преимуществ стандартной инъекции контекстной зависимости (CD) и стандартного клиента JAX-RS (нового с Java EE 7). Также приятно иметь такие сервисы, как JMS, JPA.

Вопрос в том, как я могу написать/аннотировать основной метод стандартным образом? @Inject по методу нехорошо, потому что такие методы должны быстро возвращаться. @Schedule не идеален, потому что он работает периодически, если я программно не определяю текущее системное время.

Лучшее, что я мог придумать, это установить одноразовый Timer в методе @Inject и аннотировать мой основной метод с помощью @Timeout.

Как-то это кажется немного хрупким или неэлегантным. Есть ли лучший стандартный способ запуска службы? Некоторые аннотации, которые просто заставляют его начинать и идти?

Кроме того, как Каков наилучший стандартный способ прервать и отключить службу при развертывании?

+0

Ваш вопрос немного извилистые. Если вы запускаете приложение в контейнере приложения, то почему вы определяете основной метод? Просто создайте однопользовательский EJB для запуска с помощью метода ['@ Schedule'] (http://docs.oracle.com/javaee/6/api/javax/ejb/Schedule.html). – Perception

+0

@ Превращение извилистой является отражением моего отсутствия ясности, отсюда и вопрос. '@ Schedule' занимает некоторое время. В какое время я должен аннотировать метод? Я не хочу, чтобы он запускался периодически. Метод должен выполняться ровно один раз. Если '@ Schedule' принимает интервал после развертывания, это будет идеально, но это не так. Могу ли я использовать '@Schedule ... myfunc (Таймер таймера)' и отменить входящий таймер и использовать 'TimerService' установить таймер интервала для запуска' @Timeout ... mymain() 'звуков. – necromancer

+0

Не знаю, отредактировал ли вы свой вопрос, или я пропустил нижнюю часть. Клянусь, он читает разные. Во всяком случае, одна идея - использовать startup, singleton bean и создать таймер в методе @PostConstruct. Или вставьте стороннюю библиотеку, такую ​​как Quartz, и запланируйте одноразовое задание, чтобы начать работу, когда ваше приложение развернуто. Каковы требования к расписанию для работы (при развертывании приложения, в определенный день, по запросу?). – Perception

ответ

2

Если вы можете использовать EJB с (или вместо) CDI, то попробуйте @Singleton + @Startup аннотаций для фасоли и @PostConstruct для метода main().

@Singleton 
@Startup 
public class YourBean { 

@Stateless 
public static class BeanWithMainMethod{ 

    @Asynchronous 
    public void theMainMethod(){ 
     System.out.println("Async invocation"); 
    } 
} 

    @EJB 
    private BeanWithMainMethod beanWithMainMethod; 

    @PostConstruct 
    private void launchMainMethod(){ 
     beanWithMainMethod.theMainMethod(); 
    } 
} 
+0

Я думал, что контейнер убьет его, если '@ PostConstruct' не вернется достаточно скоро. вы пробовали это с помощью долгого метода? – necromancer

+0

Развертывание не удастся, если методMainMethod не возвращается в течение длительного времени, поэтому лучше использовать @Asyncronous или события CDI. – gluckonavt

+0

спасибо за разъяснение, рекомендуется для исправления (было бы неплохо, если бы вы могли отредактировать свой ответ тоже!) – necromancer

3

Когда PostConstruct долго работает, разъединить с событиями:

@Singleton 
@Startup 
public class YourBean{ 
@Inject 
private Event<XXX> started; 
@PostConstruct 
private void theMainMethod(){ 
    started.fire(new XXX()); 
} 
public void handleStarted(@Observes XXX started) { 
    // the real main method. 
} 

}

+0

Спасибо @JanGalinski, кстати, что другой вариант должен был использовать '@Asynchronous public void handleStarted()', но я не мог заставить его быть вызванным асинхронно из метода '@ PostConstruct'. Как вы думаете, что лучше - '@ Asynchronous' или' @ Observes'? Любая идея, что мне нужно сделать, чтобы сделать асинхронный вызов метода в одном и том же компоненте из '@ PostConstruct' в том же компоненте? Спасибо за большое предложение в то же время. – necromancer

+0

Ну, нет стандартного способа запросить отмену метода '@ Observes'. С помощью '@ Asynchronous' можно запросить отмену метода с помощью возвращаемого« Будущего ». Хотя это можно моделировать нестандартным образом, в будущей версии Java EE программист, скорее всего, сможет запросить, чтобы стандартный запрос на отмену фактически прерывал поток, когда он находится в блокирующем вызове, что значительно улучшит его отзывчивость и очистить структуру тоже. Эта ожидаемая функциональность не может быть реализована программистом самостоятельно. Таким образом, '@ Asynchronous' выигрывает IMO. – necromancer