Это 18-й день моего участия в Gengwen Challenge.Подробности о мероприятии:Обновить вызов
Прежде всего, позвольте мне рассказать о том, почему я использую события.Например, я создаю заказ сейчас, но после того, как я его успешно создам, я должен отправить клиенту текстовое сообщение и напоминание по электронной почте.Это занимает много времени. для ряда операций без создания заказа, но мне все еще приходится отправлять текстовые сообщения и электронные письма.В этот период также вызываются другие службы для достижения трудоемкой и неудовлетворительной удовлетворенности клиентов, поэтому метод использования можно сказать как следует:
- ActiveMQ (асинхронный)
- Используйте мониторинг весенних событий (синхронный + асинхронный)
Слушатели событий, поддерживаемые Spring
Что такое контекст приложения
Это ядро Spring.Context обычно интерпретируется как контекст, но лучше понимать его как контейнер. ApplicationContext — это контейнер приложения. Spring помещает Bean (объект) в контейнер, и его нужно вынуть через метод get. Этот интерфейс предоставляет возможность настройки приложений Spring.При запуске приложения реализация этого интерфейса доступна только для чтения, но его содержимое может быть перезагружено, если реализация поддерживает это.
Подведем итог:ApplicationContext大概提功能如下能力:
- Получите метод bean factory компонента приложения, эта способность наследует org.springframework.beans.factory.ListableBeanFactory
- Возможность загрузки файлов ресурсов, эта способность наследуется от org.springframework.core.io.ResourceLoader
- Публиковать события для зарегистрированных прослушивателей, эта возможность наследуется от ApplicationEventPublisher.
- Предоставляет интернационализированный доступ к сообщениям, который наследуется от MessageSource.
После хорошего понимания ApplicationContext давайте взглянем на мониторинг событий, предоставляемый Spring. Чтобы реализовать возможность мониторинга событий, Spring предоставляет нам два интерфейса/абстрактных класса верхнего уровня, ApplcationEvent: абстрактный класс только с одним конструктором и длинной целочисленной меткой времени. Наше пользовательское событие Application должно наследовать этот абстрактный класс ApplicationListener: это интерфейс только с одним методом onApplicationEvent, и каждый класс, реализующий интерфейс, должен реализовать этот метод сам по себе. Мониторинг событий Spring основан на стандартном режиме наблюдателя.Если bean-компонент, который реализует ApplicationListener, развернут в ApplicationContext, когда ApplicationEvent публикуется в ApplicationContext, bean-компонент будет уведомлен и выполнит определенную обработку. Из приведенного выше отрывка мы можем легко прийти к двум мыслям:
- Как bean-компоненты, реализующие ApplicationListener, развертываются в ApplicationContext
- Как ApplicationEvent публикуется в ApplicationContext
Таким образом, полное событие состоит из трех частей: источника события, выпуска события и прослушивателя события.
пример кода
объявить событие
public class SendEmailEvent extends ApplicationEvent {
private String message;
public SendEmailEvent(Object source, String message) {
super(source);
this.message = message;
}
public String sendEmail(){
return message;
}
}
выпуск события
@Component
@Slf4j
public class SendEmailEventPublisher {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
public void publish(final String message) {
log.info("publis a SendEmailEvent,message:{}", message + " time: " + LocalTime.now());
SendEmailEvent sendEmailEvent = new SendEmailEvent(this, message);
applicationEventPublisher.publishEvent(sendEmailEvent);
}
}
прослушиватель событий
Первый метод мониторинга событий
@Component
@Slf4j
public class SendEmailListener implements ApplicationListener<SendEmailEvent> {
@Override
public void onApplicationEvent(SendEmailEvent sendEmailEvent) {
String s = sendEmailEvent.sendEmail();
log.info("SendRegisterEmailListener message: " + s+" time: "+ LocalTime.now());
}
}
Метод реализации прослушивателя событий 2
@Component
@Slf4j
public class SendEmailListener2 {
@EventListener
public void sendEmmail(SendEmailEvent sendEmailEvent){
String s = sendEmailEvent.sendEmail();
log.info("SendRegisterEmailListener message: " + s+" time: "+ LocalTime.now());
}
}
контрольная работа
@RunWith(SpringRunner.class)
@SpringBootTest
public class SendEmailEventPublisherTest {
@Resource
private SendEmailEventPublisher sendEmailEventPublisher;
@Test
public void publish() {
sendEmailEventPublisher.publish("啦啦啦");
}
}
События Spring синхронны по умолчанию, а асинхронность включается путем добавления @EnableAsync в класс запуска Application. Используя аннотацию метода, @Async может воздействовать на метод выполнения слушателя и выполнять его асинхронно. @Async без параметров по умолчанию использует пул потоков SpringBoot по умолчанию. Рекомендуется использовать собственный пул потоков:
@Configuration
public class ThreadPoolConfig {
@Bean("executor")
public Executor getExecutor() {
ThreadPoolExecutor executor = new ThreadPoolExecutor(10,
20,
60,
TimeUnit.SECONDS,
new ArrayBlockingQueue(10000));
return executor;
}
}
Суммировать
- Благодаря механизму событий код можно разделить, чтобы он был очень чистым и расширяемым;
- Механизм асинхронной обработки времени может повысить скорость отклика программы, а внутренний пул потоков значительно повысит эффективность параллелизма программы.
- Условные и универсальные слушатели позволяют уменьшить количество явных логических суждений, делая каждый слушатель более атомарным.