Статьи

Обновление JSR 365: копание в CDI 2.0

Контексты и Dependency Injection 2.0 ( JSR 365 ) — это обновление CDI 1.2, которая в настоящее время является частью платформы Java EE 7. В настоящее время он находится на стадии общественного обзора . Для тех из вас, кто не очень знаком с CDI, он определяет мощный набор дополнительных услуг, которые действуют как гель, помогающий улучшить координацию и структуру кода приложения. Для более подробной информации, пожалуйста, посетите страницу спецификации .

CDI 2.0 расширяет возможности использования служб контекстов и инъекций зависимостей и для Java SE, поскольку теперь он предназначен для платформ Java SE и Java EE. Спецификация CDI была разделена на 3 части: Часть I — Базовый CDI , Часть II — CDI в Java SE и Часть III — CDI в Java EE . Основные изменения для CDI 2.0:

  • Лучшее выравнивание с Java SE 8
  • API для загрузки CDI в приложении Java SE
  • Возможность обеспечить заказ наблюдателя
  • Способность запускать асинхронные события
  • Новые интерфейсы конфигураторов для элементов интерфейса поставщика услуг (SPI)
  • Возможность настроить или наложить вето на метод наблюдателя в событии ProcessObserverEvent
  • Поддержка встроенной реализации конкретных типов аннотаций
  • Добавление интерфейса InterceptionFactory, который позволяет создавать экземпляр оболочки, чьи вызовы методов перехватываются перехватчиками методов и перенаправляются в предоставленный экземпляр.

Я призываю вас взглянуть на проект публичного обзора CDI 2.0 для получения более подробной информации о специфике каждого из перечисленных улучшений, а также полного списка новых функций. Прочитайте проект и предоставьте отзыв экспертной группе. Все необходимые подробности для обеспечения обратной связи можно найти на странице JSR 365 . Чтобы начать тестирование, создайте новое приложение Java EE на основе maven в своей любимой IDE и добавьте следующие зависимости:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<dependency>
 
<groupid>javax.enterprise</groupid>
 
<artifactid>cdi-api</artifactid>
 
<version>2.0-PFD</version>
 
</dependency>
 
<dependency>
 
<groupid>org.jboss.weld</groupid>
 
<artifactid>weld-core-bom</artifactid>
 
<version>3.0.0.Alpha14</version>
 
<type>pom</type>
 
</dependency>

В этом посте мы рассмотрим одну из новых функций, чтобы вы начали работать с API. Давайте посмотрим на асинхронные события. До CDI 2.0 события могли запускаться только синхронно. Они были улучшены в этой последней итерации для асинхронной обработки. Вот как это работает:

Создать событие какого-то типа. Затем запустите событие в асинхронном режиме и обработайте его соответствующим образом после завершения события. В этом примере я создал класс MovieEvent, который будет использоваться всякий раз, когда для объекта Movie происходит постоянное событие. Класс MovieEvent выглядит следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class MovieEvent {
     
    private String message;
    private Movie movie;
     
    public MovieEvent(String message, Movie movie){
        this.message = message;
        this.movie = movie;
    }
     
    public String getMessage(){
        return this.message;
    }
     
    public void setMessage(String message){
        this.message = message;
    }
     
    public Movie getMovie(){
        return this.movie;
    }
     
    public void setMovie(Movie movie){
        this.movie = movie;
    }
     
}

В следующем сценарии мы запускаем событие, когда сохраняется новый фильм. Следующий код находится в компоненте MovieController CDI примера приложения JSF:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@Named("movieController")
@SessionScoped
public class MovieController implements Serializable {
 
    @EJB
    private com.mycompany.cditest.session.MovieFacade ejbFacade;
    private List items = null;
    private Movie selected;
     
    @Inject
    Event<MovieEvent> movieEvents;
. . .
   private void persist(PersistAction persistAction, String successMessage) {
        if (selected != null) {
            setEmbeddableKeys();
            try {
                if (persistAction != PersistAction.DELETE) {
                    getFacade().edit(selected);
                    movieEvents.fireAsync(new MovieEvent("New Movie Released", selected))
                            .whenComplete((event, throwable) -> {
                                if(throwable != null){
                                    System.out.println("Error has occurred: " + throwable.getMessage());
                                } else {
                                    System.out.println("Successful Movie Processing...");
                                }
                            });
                } else {
                    getFacade().remove(selected);
                }
                JsfUtil.addSuccessMessage(successMessage);
            } catch (Exception ex) {
                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
                JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            }
        }
. . .

Когда событие вызывается, оно создает новый объект MovieEvent и, если оно успешно завершается, печатается сообщение, указывающее на успешность. В этом примере поток используется для обработки действия whenComplete.

Не стесняйтесь клонировать репозиторий, расположенный по адресу https://github.com/juneau001/CdiTest, и сдать тест CDI 2.0 на спин. Этот пример — всего лишь один простой тест CDI 2.0. Вы можете клонировать и использовать этот тестовый проект в качестве отправной точки для работы с другими аспектами спецификации. Следите за JSR 365, который в настоящее время находится на этапах общественного рассмотрения.