Статьи

События Java EE6: легкая альтернатива JMS

Функцией, о которой я собираюсь рассказать сегодня, является механизм событий, который есть в java EE 6. Общая идея состоит в том, чтобы вызвать событие и позволить слушателю события его забрать.

Я создал этот пример, который совершенно бесполезен, но его простота помогает мне сосредоточиться на важных вещах. Я собираюсь запустить LogEvent из моего действия поддержки, которое будет регистрироваться в java.util.Logger.

Первое, что мне нужно, это создать POJO, который содержит мое сообщение журнала и мой LogLevel.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
public class LogMessage implements Serializable {
  
    private final String message;
    private final Level level;
  
    LogMessage(String message, Level level) {
        this.message = message;
        this.level = level;
    }
  
    public String getMessage() {
        return message;
    }
  
    public Level getLevel() {
        return level;
    }
}

Теперь, когда у меня есть оболочка для данных, мне нужно что-то, чтобы вызвать событие, и что-то, чтобы его забрать. Первое, что я создаю, — это мой метод запуска события.

Благодаря CDI я могу ввести событие.

1
@Inject Event<LogMessage> event;

Так что нам просто нужно уволить.

1
event.fire(new LogMessage("Log it baby!", Level.INFO));

Теперь событие запускается, и если никто не зарегистрирован, чтобы забрать его, оно исчезает, и мы создаем слушателя. Слушателям нужен метод с одним параметром — универсальным типом, который присваивается предыдущему событию. LogMessage.

1
2
3
4
5
6
public class LogListener {
    private static final Logger LOGGER = Logger.getAnonymousLogger();
    public void process(@Observes LogMessage message){
        LOGGER.log(message.getLevel(), message.getMessage());
    }
}

Аннотация @Observe слушает все события с LogMessage. Когда событие запускается, этот метод будет запущен.

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

Все это происходит синхронно. Когда мы хотим заменить оператор log медленным вызовом базы данных в таблицу журналов, мы можем сделать нашу работу тяжелее, чем она должна быть.

То, что я ищу, это создать асинхронный вызов. Пока мы поддерживаем EJB, мы можем преобразовать наш Listener в EJB, добавив аннотацию @Stateless поверх него. Теперь это корпоративный бин. Это ничего не меняет в нашей проблеме с синхронизацией / асинхронностью, но EJB 3.1 поддерживает асинхронные операции. Так что, если мы добавим аннотацию @Asynchronous поверх нее. Он будет асинхронно выполнять наш оператор регистрации.

1
2
3
4
5
6
7
8
@Stateless
@Asynchronous
public class LogListener {
    private static final Logger LOGGER = Logger.getAnonymousLogger();
    public void process(@Observes LogMessage message){
        LOGGER.log(message.getLevel(), message.getMessage());
    }
}

Если мы хотим объединить ведение журнала базы данных и ведение журнала консоли, мы можем просто создать несколько методов, которые прослушивают одно и то же событие.

Это отличный способ создать легкое приложение с очень гибкими компонентами. Альтернативное решение этой проблемы — использовать JMS, но вам не нужна тяжелая конфигурация для такого рода слабой связи.

Ссылка: Java EE6 Events, легкая альтернатива JMS от нашего партнера по JCG Джелле Виктор из блога Styled Ideas .

Статьи по Теме :