记录 ApplicationEventPublisher.publishEvent() 调用
Log ApplicationEventPublisher.publishEvent() calls
我有一个 Spring Boot 2.2 应用程序,它在不同的包中发布和使用 spring 应用程序事件。现在我想在每次 ApplicationEventPublisher.publishEvent()
.
发布事件时记录
一个解决方案可能是编写我自己的事件发布者,例如:
public class LoggableApplicationEventPublisher implements ApplicationEventPublisher {
private final ApplicationEventPublisher eventPublisher;
private final Logger logger;
public ApplicationEventLogger(ApplicationEventPublisher eventPublisher, Logger logger) {
this.eventPublisher = eventPublisher;
this.logger = logger;
}
@Override
public void publishEvent(ApplicationEvent event) {
eventPublisher.publishEvent(event);
logger.info("--> Emitting {}", event);
}
}
另一种解决方案可能是使用面向方面的编程并编写一个在每次 publishEvent()
被触发时触发的方面:
@Aspect
@Component
public class EventPublishAspect {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Pointcut("execution(* org.springframework.context.ApplicationEventPublisher.*(..))")
public void logPublishEvent() {
}
@After("logPublishEvent()")
public void log(JoinPoint point) {
Object[] lArgs = point.getArgs();
LOG.info("Triggered", lArgs[0]);
}
}
我已经正确设置了所有内容(以及依赖项)并且这个示例适用于其他切入点(例如调用我的服务的特定方法)。
但是,此方面不适用于 ApplicationEventPublisher
-接口声明的切入点。你知道为什么不吗?好像spring boot injects AbstractApplicationContext
on runtime,其实就是实现了这个接口
不需要方面的解决方案(并且启动时间更快?)
@Primary
@Bean
DelegatingApplicationEventPublisher applicationEventPublisher(ApplicationContext applicationContext) {
new DelegatingApplicationEventPublisher(applicationContext)
}
@Slf4j
@RequiredArgsConstructor
public class DelegatingApplicationEventPublisher implements ApplicationEventPublisher {
private final ApplicationContext context;
@Override
public void publishEvent(ApplicationEvent event) {
logEvent(event);
context.publishEvent(event);
}
@Override
public void publishEvent(Object event) {
logEvent(event);
context.publishEvent(event);
}
private void logEvent(Object event) {
if (event instanceof PayloadApplicationEvent payloadApplicationEvent) {
log.debug(markers("eventName", payloadApplicationEvent.getPayload().getClass(), "event", payloadApplicationEvent.getPayload()), "publishing...");
} else {
log.debug(markers("eventName", event.getClass(), "event", event), "publishing ...");
}
}
}
我有一个 Spring Boot 2.2 应用程序,它在不同的包中发布和使用 spring 应用程序事件。现在我想在每次 ApplicationEventPublisher.publishEvent()
.
一个解决方案可能是编写我自己的事件发布者,例如:
public class LoggableApplicationEventPublisher implements ApplicationEventPublisher {
private final ApplicationEventPublisher eventPublisher;
private final Logger logger;
public ApplicationEventLogger(ApplicationEventPublisher eventPublisher, Logger logger) {
this.eventPublisher = eventPublisher;
this.logger = logger;
}
@Override
public void publishEvent(ApplicationEvent event) {
eventPublisher.publishEvent(event);
logger.info("--> Emitting {}", event);
}
}
另一种解决方案可能是使用面向方面的编程并编写一个在每次 publishEvent()
被触发时触发的方面:
@Aspect
@Component
public class EventPublishAspect {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Pointcut("execution(* org.springframework.context.ApplicationEventPublisher.*(..))")
public void logPublishEvent() {
}
@After("logPublishEvent()")
public void log(JoinPoint point) {
Object[] lArgs = point.getArgs();
LOG.info("Triggered", lArgs[0]);
}
}
我已经正确设置了所有内容(以及依赖项)并且这个示例适用于其他切入点(例如调用我的服务的特定方法)。
但是,此方面不适用于 ApplicationEventPublisher
-接口声明的切入点。你知道为什么不吗?好像spring boot injects AbstractApplicationContext
on runtime,其实就是实现了这个接口
不需要方面的解决方案(并且启动时间更快?)
@Primary
@Bean
DelegatingApplicationEventPublisher applicationEventPublisher(ApplicationContext applicationContext) {
new DelegatingApplicationEventPublisher(applicationContext)
}
@Slf4j
@RequiredArgsConstructor
public class DelegatingApplicationEventPublisher implements ApplicationEventPublisher {
private final ApplicationContext context;
@Override
public void publishEvent(ApplicationEvent event) {
logEvent(event);
context.publishEvent(event);
}
@Override
public void publishEvent(Object event) {
logEvent(event);
context.publishEvent(event);
}
private void logEvent(Object event) {
if (event instanceof PayloadApplicationEvent payloadApplicationEvent) {
log.debug(markers("eventName", payloadApplicationEvent.getPayload().getClass(), "event", payloadApplicationEvent.getPayload()), "publishing...");
} else {
log.debug(markers("eventName", event.getClass(), "event", event), "publishing ...");
}
}
}