Guava EventBus를 동기화하여 사용 중입니다. 구독자 중 하나가 예외를 throw하면 전체 트랜잭션을 롤백하는 방법은 무엇입니까? EventBus 가입자가 잡히지 않을 예외를 던지려면 어떻게해야합니까?Guava EventBus 가입자로부터 예외 예외 발생
답변
게시자와 구독자간에 가변적으로 java.lang.ThreadLocal
을 사용하여 해결했습니다.
출판사 로컬 예외 스레드 판독
public void publish(Event event) {
eventBus.post(event);
if(threadLocalException != null) {
Store threadLocalException in some variable say e
Clear threadLocalException variable
throw e;
}
}
가입자 스레드 로컬 변수
public abstract class EventSubscriber<T extends Event> {
@Subscribe
public void invoke(T event) {
try {
handle(event);
} catch (Exception e) {
Set thread local variable to e
}
}
protected abstract void handle(T event);
}
Guava의 EventBus
클래스의 소스 코드를 살펴 보는 것 만하면됩니다.
은의이 끝에서 시작하자 :
나는 EventBus 가입자에 의해 체포되지 않습니다 예외를 던질 수 있습니까?
com.google.common.eventbus.Dispatcher#dispatch
방법으로 구독자의 메서드가 하나씩 차례로 호출됩니다. 구독자의 메서드를 호출하기 위해 EventBus는 리플렉션의 메서드 Method#invoke
을 사용합니다.이 메서드는 호출 된 메서드가 예외를 throw하면 InvocationTargetException
을 차례로 throw합니다. 당신은 또한 볼 수 있듯이
로 처리됩니다 (당신의 Exception
감싸됩니다) InvocationTargetException
은 다음과 같습니다
} catch (InvocationTargetException e) {
if (e.getCause() instanceof Error) {
throw (Error) e.getCause();
}
throw e;
}
, 예외가 그런 식으로 처리됩니다
try {
invokeSubscriberMethod(event);
} catch (InvocationTargetException e) {
bus.handleSubscriberException(e.getCause(), context(event));
}
TL : DR
따라서 예외 처리기를 생략하는 유일한 방법은 EventBus
입니다. Exception
을 던지지 말고, 구독 방법에 Error
을 던지십시오. 이는 분명히 나쁜 습관입니다.
가입자가 Exception을 throw하는 경우 전체 트랜잭션을 어떻게 롤백 할 수 있습니까?
EventBus
예외 처리기는 com.google.common.eventbus.EventBus#handleSubscriberException
메서드를 호출하여 예외를 처리합니다.
try {
exceptionHandler.handleException(e, context);
} catch (Throwable e2) {
// logging
}
따라서 예외 처리기에서 발생한 모든 예외는 도움이되지 않습니다.
- 하나 던져 오류 : 두 가지 선택이있다. 나는 그런 것들을위한 최고의 장소가 명백하게
EventBus
예외 핸들러라고 생각한다.
EventBus를 상속하고 예외를 던질 이벤트 버스를 만드십시오. 패키지는 com.google.common.eventbus인데 handleSubscriberException은 내부 메소드입니다.
package com.google.common.eventbus;
import com.google.common.util.concurrent.MoreExecutors;
/**
* A eventbus wihch will throw exceptions during event handle process.
* @author ytm
*
*/
public class ErrorThrowEventBus extends EventBus {
/**
* Creates a new EventBus with the given {@code identifier}.
*
* @param identifier a brief name for this bus, for logging purposes. Should be a valid Java
* identifier.
*/
public ErrorThrowEventBus(String identifier) {
super(
identifier,
MoreExecutors.directExecutor(),
Dispatcher.perThreadDispatchQueue(),
LoggingHandler.INSTANCE);
}
/**
* Creates a new EventBus with the given {@link SubscriberExceptionHandler}.
*
* @param exceptionHandler Handler for subscriber exceptions.
* @since 16.0
*/
public ErrorThrowEventBus(SubscriberExceptionHandler exceptionHandler) {
super(
"default",
MoreExecutors.directExecutor(),
Dispatcher.perThreadDispatchQueue(),
exceptionHandler);
}
/**
* Just throw a EventHandleException if there's any exception.
* @param e
* @param context
* @throws EventHandleException
*/
@Override
void handleSubscriberException(Throwable e, SubscriberExceptionContext context) throws EventHandleException {
throw new EventHandleException(e);
}
}
- 1. Guava EventBus dispatching
- 2. Guava EventBus unit tests
- 3. Guava 중복 키 예외 예외 : IllegalArgumentException
- 4. 예외 예외 발생
- 5. 작업. 예외 예외 발생
- 6. 예외 예외 발생
- 7. PropertyGrid에 예외 예외 발생
- 8. 클로저에서 예외 예외 발생
- 9. 바운드 예외 예외 발생
- 10. Firebase 서비스에서 EventBus 3.0을 사용하여 예외 발생 - Android
- 11. 예외 조항에서 예외 처리 발생
- 12. 모킷 토 예외 예외 발생
- 13. 예외 발생 및 인쇄 예외?
- 14. ASP.NET 예외 예외 발생 C#
- 15. UI 스레드에서 예외 예외 발생
- 16. UI 스레드에서 예외 예외 발생
- 17. AppDomain.AssemblyLoad 이벤트에서 예외 예외 발생
- 18. 예외 예외 발생 - 기본값 설정
- 19. 예외 발생
- 20. 예외 발생
- 21. Guava EventBus + Hazelcast Spring 구성
- 22. Guava EventBus : 특수 효과가없는 구독?
- 23. WPF : "StaticResource가 해결되지 않음"예외 발생 예외?
- 24. 루프 레코드 추가하기 예외 예외 발생
- 25. CSV 내보내기 응답. 예외 예외 발생
- 26. 잘못된 배열 길이에 대한 예외 예외 발생
- 27. .NET 웹 서비스에서 예외 예외 발생
- 28. 단순 커서 어댑터 예외 예외 발생 잘못된 인수 예외?
- 29. Android에서 팽창 예외 발생
- 30. 예외 발생 원인 : java.lang.UnsupportedClassVersionError
I 상기 예외를 설정하는 클래스 감싸 필요를 발생 클래스 래핑해야 이 중 하나가 가능하다면 놀라움을 금치 못할 것입니다. –
이것이 가능하지 않다면 트랜잭션이 될 수없는 이벤트 버스의 제한 사항이 아닙니까? – Shikhar
예. 당연하지. –