В повседневной разработке часто встречается, что один метод завершен, а другой метод нужно уведомить.
Например, после того, как пользователь зарегистрировался, ему необходимо отправить ему электронное письмо. Такой основной бизнес включает в себя множество дочерних предприятий,
Если требования к транзакции не очень строгие, вы можете попробовать публикацию событий и подписку SpringBoot.
класс событий
Сначала вам нужно определить событие, этот класс наследуетApplicationEvent
этот абстрактный класс.
import org.springframework.context.ApplicationEvent;
/**
* 定义一个自定义事件,继承ApplicationEvent类
*
* @author lww
* @date 2020-04-09 17:41
*/
public class MyApplicationEvent extends ApplicationEvent {
private static final long serialVersionUID = 1L;
public MyApplicationEvent(Object source) {
super(source);
System.err.println("发布事件:source = " + source);
}
}
Опубликовать событие
Публикация событий проста, внедрениеApplicationContext
,перечислитьcontext.publishEvent(new MyApplicationEvent("发布事件啦"));
Ну такое событие публикуется.
import com.ler.eventdemo.event.MyApplicationEvent;
import javax.annotation.Resource;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author lww
* @date 2020-04-09 18:05
*/
@RestController
public class HelloController {
@Resource
private ApplicationContext context;
@GetMapping("/hello")
public String hello(String name) {
context.publishEvent(new MyApplicationEvent("发布事件啦"));
return "Hello " + name;
}
}
В событии публикации есть маленькая иконка, и при нажатии на нее произойдет переход к месту, где событие подписано (в идее).
Подписаться на события
Вместе с событием событие публикуется, и следующим шагом является подписка на событие. Тоже очень просто, нужно просто написать слушатель
import com.ler.eventdemo.event.MyApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
/**
* 定义一个事件监听器 MyApplicationListener
*
* @author lww
* @date 2020-04-09 17:42
*/
@Component
public class MyApplicationListener {
@EventListener
public void onApplicationEvent(MyApplicationEvent event) {
System.err.println("接收到事件:" + event.getClass());
}
}
Некоторые говорят, чтоApplicationListener
Интерфейс, после тестирования установлено, что нет необходимости реализовывать какой-либо интерфейс. просто добавь@EventListener
Аннотация, а затем параметр указывает, какое событие, и все.
В событии подписки также есть небольшая иконка, и щелчок по ней приведет к переходу к событию публикации (в идее).
@TransactionalEventListener
@TransactionalEventListener
и@EventListener
один короткийTransactional
, эта транзакция означает,
Время отправки событий может быть привязано к транзакциям.
- TransactionPhase.BEFORE_COMMIT перед фиксацией
- TransactionPhase.AFTER_COMMIT после фиксации
- TransactionPhase.AFTER_ROLLBACK после отката
- TransactionPhase.AFTER_COMPLETION после завершения транзакции
дефолтTransactionPhase.AFTER_COMMIT
.
При указании времени выпуска следует избегать ситуации, когда, например, регистрация пользователя включает в себя некоторые трудоемкие операции, и некоторые из этих операций являются асинхронными и неблокирующими. Когда выполняется метод, который публикует событие. Пользователь может быть еще не создан. Если событие опубликовано в это время, оно может не получить пользователя при выполнении на стороне слушателя. И если он выполняется после фиксации транзакции, этого не будет.
эта аннотациянетСкажите, какова транзакционная связь между методом, который публикует событие, и методом ответа слушателя. Между ними по-прежнему нет никаких дел. Атомарность, согласованность не могут быть гарантированы.
Если вы хотите реализовать транзакцию, это возможно.Вы можете сначала убедиться, что издатель событий выполнен и транзакция отправлена. Затем подписчик следует правилу идемпотентности, Если подписчик терпит неудачу, введите механизм повторной попытки. Немного похоже на фиксацию сегмента RocketMQ, возврат транзакций и механизм повторных попыток. Это может быть реализовано в соответствии с этой идеей.
принцип
-
ApplicationContext
интерфейс наследуетApplicationEventPublisher
интерфейс, так что естьpublishEvent
метод, который можно использовать для публикации задач. -
ApplicationListener
интерфейс наследуетEventListener
интерфейс, который имеетonApplicationEvent
способ прослушивания событий.
существуетorg.springframework.context.support.AbstractApplicationContext#refresh
метод,org.springframework.context.support.AbstractApplicationContext#registerListeners
в
Как видите, поиск осуществляется при регистрации слушателя.ApplicationListener
Если мы не реализуем интерфейс, как нам его зарегистрировать?
@EventListener
В комментарии есть это предложение, посмотрите на этот метод этого классаorg.springframework.context.event.EventListenerMethodProcessor#processBean
Здесь найдите с помощью@EventListener
Метод аннотирования также будет добавлен вConfigurableApplicationContext
(ApplicationContext
класс реализации),
как слушатель. так не реализованоApplicationListener
, также можно использовать в обычном режиме.
Обратите внимание, что вам нужно использовать класс конфигурации Java.Если вы используете конфигурацию xml, вам нужно добавить<context:annotation-config/>
или<context:component-scan/>
и@TransactionalEventListener
Включают@EventListener
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@EventListener
public @interface TransactionalEventListener {
......
}
@TransactionalEventListener
Зависит отorg.springframework.transaction.event.TransactionalEventListenerFactory
иметь дело с,
в этом методеorg.springframework.transaction.event.TransactionalEventListenerFactory#createApplicationListener
созданныйorg.springframework.transaction.event.ApplicationListenerMethodTransactionalAdapter#ApplicationListenerMethodTransactionalAdapter
существуетorg.springframework.transaction.event.ApplicationListenerMethodTransactionalAdapter#onApplicationEvent
В этом методе используйтеTransactionSynchronizationEventAdapter
управлять делами.
Суммировать
Публикация и подписка на события SpringBoot очень проста и удобна в использовании, а также широко используется во фреймворке SpringBoot.Давайте потренируемся быстро, друзья.
В этой статье используетсяmdniceнабор текста