Рубрики
Без рубрики

Контексты и внедрение зависимостей (CDI) 2.0

В этом посте я расскажу подробно чуть-чуть возможности Java CDI и как могут быть использованы для улучшения кода. С тегами джакарта, java ee, java, java cdi.

CDI с особыми особенностями может быть основной адо Джакарта EE ed o Микро profile.io . В основе всех других, и используется практически во всех других.

Для тех, кто не знает, спецификация, вы можете заблудиться. Так было со мной. Вы столкнулись с классами так:

@ApplicationScoped
public class UserService {
    @Inject
    private UserRepository userRepository;

    public Optional findById(long userId) {
        return Optional.ofNullable(userRepository.find(userId));
    }
}

И если вы спросите:

  • Да, кто создает экземпляр этого класса?
  • Да, кто создает экземпляр этого класса? Как я создал Да, кто создает экземпляр этого класса? Как я создал userRepository ?
  • Та, кем инстанция эсса классе? Como eu конфигурирует пользовательское хранилище Como eu uso Пользовательский сервис?

Да, кто создает экземпляр этого класса? Как я создал userRepository, Как я использую UserService? Если вы не знаете, как ответить на эти вопросы, мы будем там….

Да, кто создает экземпляр этого класса? Как я создал userRepository, Как я использую UserService? Если вы не знаете, как ответить на эти вопросы, мы будем там…. Первая версия Contexts and Dependency Injection for Java EE (CDI) вошла в Java EE 6, и быстро стал одним из самых важных и популярных спецификации платформы.

Да, кто создает экземпляр этого класса? Как я создал userRepository, Как я использую UserService? Если вы не знаете, как ответить на эти вопросы, мы будем там…. Первая версия || Contexts and Dependency Injection for Java EE (CDI) || вошла в Java EE 6, и быстро tornCDI определяет набор спецификаций, что позволяет хорошая модульность кода проекта: или одна из самых важных и популярных спецификации платформы.

  • Жизненный цикл четко определены объекты и их контекстов. Также расширяемый набор контекстов.
  • Сложные и механизм впрыска с сильной типизации без конфигурации
  • Кронштейн создания Компонентов, полностью desacoplados
  • Интеграция с JSF
  • Decorators
  • Перехватчики
  • Программа перехватчиков, управляемая событиями

Перехватчики Programação Управляемый событиями Escopo

Перехватчики программируют управляемый событиями побег из Java-КОДА, определяющего базовые параметры API uma, фреймворки для внедрения зависимостей, которые могут быть использованы для удаления безопасных для типов бобов, автоматического удаления контейнеров и т. Д.

Потому что использовать CDI

CDI позволяет отобрать полностью жизненного цикла объекта и его использования. Разработчик, который использует класс, не нужно знать, как создать экземпляр и не как удалить эти объекты. Позволяя, таким образом,:

  • Скорость Развития
  • Стандартизация код
  • Слабосвязанных и высокой сплоченности
  • Акцент на Бизнес-Логике

Чтобы понять, что такое Java CDI, нужно понять некоторые настройки перед.

Инверсия Управления

Инверсия управления, второй Martin Fowler , это то, что отличается от структуры Библиотеки. Инверсия управления, второй Martin Fowler , это то, что отличается от структуры Библиотеки. При использовании библиотеки, должен быть явно загружается в коде зависимостей каждого компонента. Инверсия управления,

Инверсия управления, || второй Martin Fowler || , это то, что отличается от структуры Библиотеки. При использовании библиотеки, должен быть явно загружается в коде, зависимости каждого componAo если использовать componene, зависимости каждого компонента загружаются одним и тем же, будучи || всего || за desenvolvedoProgramação по Аспектах r использовать compomenente. ente.

Инверсия управления, || второй Martin Fowler || , это то, что отличается от структуры Библиотеки. При использовании библиотеки, должен быть явно загружается в коде, зависимости каждого componAo если использовать componene, зависимости каждого компонента загружаются одним и тем же, будучи || всего || за desenvolvedoQuando если речь АОП, существует множество концепций, но мы можем быть довольно простой, а установить. Программирование на r Аспекты использования compomenente. ente. При написании кода, разработчик может отделить несколько уровней типов кодов. Те, которые определяют, что делается, функциональные требования и основные требования.

Давайте представим, что вы разрабатываете endpoint для лечения забронировать товар в корзину для покупки. Есть код забронировать элемент (1), есть код, который реализует протокол HTTP (2), и есть другие возможности, которые повысят безопасность, службы (3). 1 это основной код, 2 и 3 являются только аспектами этого кода, и могут быть определены ortogonalmente код. Как это сделать? Вамос вер сегир: Декораторы или Перехватчики!

Чтобы создать проект CDI, просто добавьте файл src/main/resources/META-INF/beans.xml проекта Maven.



Это сделает автоматически ВСЕ объекты, определенные в проекте, могут рассматриваться как один бин, и переданы aotumaticamente.

Объекты CDI, будут загружены автоматически. Для этого нужно соблюдать следующие требования:

  • Не будь Inner Class
  • Не есть абстрактный Класс, и не имеет Annotation @Decorator
  • Нет реализации интерфейса javax.enterprise.inject.spi. Расширение
  • Нао поссуй аннотацию @Наложил вето e num esta em um pacote com @Наложил вето
  • Имеет конструктор, соответствующий
    • Один конструктор без параметров
    • Параметризованный конструктор с @Inject
      • В спецификации, но не работает! Понять причины

Область видимости и Контекст

Каждый объект должен указать, какие его области. Это непосредственное влияние, когда каждый объект будет создан и удален. Или, если существует только одно или несколько одновременно. Области, pre, определяемые Java являются CDI:

Request Взаимодействие пользователя с веб-приложением в одном HTTP-запросе. @Объем запросов ограничен
Session Взаимодействие пользователя с веб-приложением через несколько HTTP-запросов. @Область действия сеанса
Application Общее состояние для всех взаимодействий пользователей с веб-приложением. @Область применения
Dependent Область действия по умолчанию, если она не указана ; это означает, что объект существует для обслуживания только одного клиента (компонента) и имеет тот же жизненный цикл, что и этот клиент (компонент). @Зависимый
Conversation Взаимодействие пользователя с приложением JavaServer Faces осуществляется в рамках явных границ, контролируемых разработчиком, которые расширяют область действия для нескольких вызовов жизненного цикла JavaServer Faces. Все длительные разговоры ограничены определенной сессией HTTPservletsession и не могут пересекать границы сеанса. @ConversationScoped

Учебное пособие по Нессе, para facilitar os exemplos, vamos тратар апенас дос эскопос Запрашивает электронное приложение.

O SessionScoped используется в проектах JSF, где есть сеанс активных пользователей.

Непосредственно

Любой объект, который отвечает всем вышеуказанным требованиям. Как вы можете увидеть в UserRepository.java поле collection вставляется и инициализированы только с использованием annotation @Inject .

@Dependent
public class UserRepository {
    [...]

    @Inject
    private MongoCollection collection;

    [...]
}

Жизненный цикл

Вместе с экземпляров, Java CDI позволяет управлять жизненным циклом объекта. Если необходимо удалить объект в то же быть удален или создавать объекты, не CDI, как это делает?

Для этого мы можем использовать аннотации @Постконструкция e @Предопределение .

Вежа о примере де Фабрика монгоклиентов . Обратите внимание, что при инициализации вызывается автоматически o мне нужно сделать построить MongoClient e ao ser removido o метод очистка .

Фабрика

И если класс не определен в моем коде, как я могу?

Для этого, мы можем инициализировать ее с помощью Factory .

Em DI ela é definida pela аннотация @Производит .

Вежа о касо де Фабрика монгоклиентов , , класс é usado pelo DE para instanciar qualquer инстанция де Монгоколлекция

Если класс MongoCollection бы Closeable, я должен был бы также implementaro методологической любя, это как:

public  void disposeMongoCollection(@Dispose MongoCollection collection) {
    // close if possible
}

А теперь, если мне нужно выбрать между реализациями различных? Как я делаю?

Этот CDI также имеет решение для этого, с низким связи. Во-первых, вы будете иметь, чтобы определить интерфейс или класс абстрактным. В наших примерах мы будем создавать HelloService с единственной целью сказать Привет .

public interface HelloService {

    public String sayHello(String username);
}

В этом интерфейсе не требуется практически ничего.

Потом нужно определить, какие будут использованы qualifiers:

@Qualifier
@Retention(RUNTIME)
@Target({ TYPE, ElementType.FIELD })
public @interface PtBr {

}

Следующим шагом является определение реализации, ниже два, которые я сделал:

@ApplicationScoped
@PtBr
public class HelloServicePtBr implements HelloService {

    @Override
    public String sayHello(String username) {
        return String.format("Olá! %s", username);
    }

}

E

@ApplicationScoped
public class HelloServiceUs implements HelloService {

    @Override
    public String sayHello(String username) {
        return String.format("Hello! %s", username);
    }

}

В обоих случаях выше, вы можете заметить, что HelloServiceUs это реализация по умолчанию, в то время как HelloServicePtBr было бы альтернативы. Так же, мы можем использовать:

public class SayHelloEndpoing {

    @Inject
    private HelloService helloService;

    // something

}

Чтобы использовать реализацию по умолчанию, и только путем добавления @Kk мы можем изменить реализацию.

public class SayHelloEndpoing {

    @Inject
    @PtBr
    private HelloService helloService;

    // something

}

Таким образом, можно поменять реализация компонента с minimas изменения в классах.

Последний feature CDI-это возможность перехвата. Это реализация того, что мы можем назвать АОП.

Давайте ясно, с какой целью, если использовать перехватчик? Удалить из кода функции, которые не входят в намерения прямой код. Например: Создание пользователя есть бизнес-правила, и сделок, сделок, имеют право на перехватчик, enquantoas бизнес-правила ДОЛЖНЫ быть выражены в коде.

Как сделать ловушку?

  1. Ваш класс должен быть перехвачены должна быть снабжена по крайней CDI
  2. Annotation , с помощью @Inherited и @InterceptorBinding , чтобы пометить метод/класс
  3. Ваш класс должен быть перехвачен, должно быть, какой-qualifier связан (она или метод)
  4. Должен быть объявлен перехватчик как в классе, как нет beans.xml .

Давайте предположим, что в некоторые классы, которые я хочу создать статистику, то обратите внимание на реализации ниже:

@Measured
@Interceptor
public class StatisticInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(StatisticInterceptor.class);

    @AroundInvoke
    public Object calculateExecutionTime(InvocationContext invocationContext) throws Exception {
        long startTime = System.currentTimeMillis();
        Object returnedValue = invocationContext.proceed();
        long endTime = System.currentTimeMillis();
        logger.info("The execution of {}.{} took {}ms", invocationContext.getMethod().getName(),
        invocationContext.getMethod().getDeclaringClass().getName(), endTime - startTime);
        return returnedValue;
    }
}

Обратите внимание, запуск! Успех! 😀

2020-05-27 13:37:16,263 INFO  [i.v.a.i.s.StatisticInterceptor] (default task-1) The execution of findByUsernameAndPassword.io.vepo.access.user.UserRepository took 6ms
2020-05-27 13:37:16,333 INFO  [i.v.a.i.s.StatisticInterceptor] (default task-1) The execution of login.io.vepo.access.user.UserEndpoint took 113ms
2020-05-27 13:37:35,087 INFO  [i.v.a.i.s.StatisticInterceptor] (default task-1) The execution of findByUsernameAndPassword.io.vepo.access.user.UserRepository took 2ms
2020-05-27 13:37:35,088 INFO  [i.v.a.i.s.StatisticInterceptor] (default task-1) The execution of login.io.vepo.access.user.UserEndpoint took 4ms
2020-05-27 13:37:40,430 INFO  [i.v.a.i.s.StatisticInterceptor] (default task-1) The execution of findByUsernameAndPassword.io.vepo.access.user.UserRepository took 2ms
2020-05-27 13:37:40,431 INFO  [i.v.a.i.s.StatisticInterceptor] (default task-1) The execution of login.io.vepo.access.user.UserEndpoint took 3ms

Последний feature, чтобы использовать CDI события. CDI обеспечивает взаимодействие asincrona и отключен внутри одной и той же JVM.

Событием может быть любой объект Java, желательно, что представляет само событие. В моем примере я использовал UserCreated и UserRemoved представлять эти действия.

Как отправить? Просто создать экземпляр producer, используя @Inject и все готово:

@Inject
private Event createdEvent;


@POST
@Secured
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public User createUser(User user) {
    logger.info("Credentials: {}", credentials);
    user.setPassword(this.passwordEncrypter.encrypt(user.getPassword()));
    this.userRepository.create(user);
    this.createdEvent.fire(new UserCreated(user.getUsername()));
    return user;
}

Пункт о событии для потребителей, баста, криар, методо ком @Наблюдатель, Созданный пользователем, Созданным пользователем Событие .

Давайте посмотрим на реализацию:

@ApplicationScoped
public class SendEmailHandler {

    private static final Logger logger = LoggerFactory.getLogger(SendEmailHandler.class);

    public void sendUserCreatedEmail(@Observes UserCreated userCreatedEvent) {
        logger.info("Sending User Created email! {}", userCreatedEvent);
    }

    public void sendUserRemovedEmail(@Observes UserRemoved userRemovedEvent) {
        logger.info("Sending User Removed email! {}", userRemovedEvent);
    }
}

CDI помочь управлять жизненным циклом объекта, и с этим уменьшается acomplamento кода. Для тех, кто не знает его, чувствует, как по волшебству, поэтому очень важно, что их команда имеет полное знание спецификации, прежде чем использовать его.

С Intercepts CDI можно удалить коды, которые ортогональны бизнес-логики, чтобы они не сорвать договоренности. Оставляя док-очистить код и разобщенным.

События, CDI-это возможность сделать ваш код более свободными, и новых возможностей, не требующих изменения кодов старых.

Хорошее использование!

Отсутствует ли что-нибудь еще? Не понимала, почему путают? Спросите, что я могу улучшить! 😀

Все примеры, приведенные в этой должности в:

vepo/cdi-учебное пособие

Учебное пособие по Java CDI с использованием Jakarta EE (Торнтейл)

Используется для проведения лекций

Основное содержание лекции в ICD .

Перед запуском, необходимо наличие базы MongoDB работает на той же машине.

docker run --rm --name mongo-db --env MONGO_INITDB_ROOT_USERNAME=root --env MONGO_INITDB_ROOT_PASSWORD=root -p 27017:27017 mongo:3.4

Для выполнения:

mvn clean thorntail:run

Оригинал: “https://dev.to/vepo/contexts-and-dependency-injection-cdi-2-0-1ae4”