vir*_*sha 2 java event-listener spring-boot
我正在从事 Spring Boot 应用程序的事件驱动设计。
代码由以下文件组成:
Spring 启动:ApplicationEvent 文件,即 MyBusinessEvent.{java
@Data
@AllArgsConstructor
public class MyBusinessEvent {
private String data;
}
Run Code Online (Sandbox Code Playgroud)事件发布者文件:MyBusinessService.java
@Slf4j
@Service
public class MyBusinessService {
private final ApplicationEventPublisher applicationEventPublisher;
@Autowired
public MyBusinessService(
ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
@Override
public void save() {
String data = "Testing event data";
MyBusinessEvent event = new MyBusinessEvent(data);
applicationEventPublisher.publishEvent(event);
}
}
Run Code Online (Sandbox Code Playgroud)事件监听器:MyBusinessEventListener.java
@Slf4j
@Component
public class MyBusinessEventListener {
@EventListener
public void handleEvent(MyBusinessEvent myBusinessEvent) {
log.info("[MyBusinessEventListener] New event received with following data: {}", myBusinessEvent);
}
}
Run Code Online (Sandbox Code Playgroud)关键是当侦听器文件包含时@EventListener,应用程序按预期工作,但当我这样做时@TransactionEventListener。例如:
TransactionalEventListener : MyBusinessEventListener.java
@Slf4j
@Component
public class MyBusinessEventListener {
@TransactionalEventListener
public void handleEvent(MyBusinessEvent myBusinessEvent) {
log.info("[MyBusinessEventListener] New event received with following data: {}", myBusinessEvent);
}
}
Run Code Online (Sandbox Code Playgroud)有@TransactionalEventListener,它不会在所有的工作。
应用程序没有通过任何异常(甚至在运行时也没有),但没有按预期进行日志记录。
是否缺少任何配置?
添加@Transactional注释MyBusinessService.save应该可以解决这个问题。
根据 java 文档,@TransactionalEventListener在@Transactional边界内工作。
这里是什么文件说,
If the event is not published within the boundaries of a managed transaction, the
* event is discarded unless the {@link #fallbackExecution} flag is explicitly set.
Run Code Online (Sandbox Code Playgroud)
如果您不希望在事务边界中使用您的服务方法,请使用 @TransactionalEventListener(fallbackExecution = true)
编辑:上述问题有三种可能的解决方案。
一世。标记class为@Transactional被视为交易
@Transactional
@Service
public class MyBusinessService {
private final ApplicationEventPublisher applicationEventPublisher;
@Autowired
public MyBusinessService(
ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
@Override
public void save() {
String data = "Testing event data";
MyBusinessEvent event = new MyBusinessEvent(data);
applicationEventPublisher.publishEvent(event);
}
}
Run Code Online (Sandbox Code Playgroud)
ii. 将具体的服务方式作为@Transactional
@Override
@Transactional
public void save() {
String data = "Testing event data";
MyBusinessEvent event = new MyBusinessEvent(data);
applicationEventPublisher.publishEvent(event);
}
Run Code Online (Sandbox Code Playgroud)
三、如果您不希望在事务边界中使用您的服务方法,请使用
@Slf4j
@Component
public class MyBusinessEventListener {
@TransactionalEventListener(fallbackExecution = true)
public void handleEvent(MyBusinessEvent myBusinessEvent) {
log.info("[MyBusinessEventListener] New event received with following data: {}", myBusinessEvent);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7157 次 |
| 最近记录: |