我有一個Java阿卡應用程序,我想爲每一個消息的單獨MDC上下文處理基於該消息內的信息,例如我已經對所有消息以下基本接口:演員MDC上下文
public interface IdMessage {
String getId();
}
此外,我對所有演員存在以下基本演員:
public class BaseActor extends AbstractActor {
private final DiagnosticLoggingAdapter log = Logging.apply(this);
@Override
public void aroundReceive(PartialFunction<Object, BoxedUnit> receive, Object msg) {
if (msg instanceof IdMessage) {
final Map<String, Object> originalMDC = log.getMDC();
log.setMDC(ImmutableMap.of("id", ((IdMessage) msg).getId()));
try {
super.aroundReceive(receive, msg);
} finally {
if (originalMDC != null) {
log.setMDC(originalMDC);
} else {
log.clearMDC();
}
}
} else {
super.aroundReceive(receive, msg);
}
}
}
和實際執行的演員:
public class SomeActor extends BaseActor {
SomeActor() {
receive(ReceiveBuilder
.match(SomeMessage.class, message -> {
...
}
}
}
我想確保SomeActor#receive()
中的所有日誌條目都具有在BaseActor
中設置的MDC上下文。爲使這項工作SomeActor#receice()
需要在與BaseActor#aroundReceive()
方法相同的線程中執行。
我沒有找到關於aroundReceive
行爲的任何信息 - 是否總是在與實際receive
方法相同的線程中執行?根據我的測試,它總是在同一個線程中執行。
爲什麼'DiagnosticLoggingAdapter'不能解決這個問題的原因在[本答案](http://stackoverflow.com/a/31237679/843660)中有解釋。至於重寫'aroundReceive',這被標記爲內部API,並且只有當你把你的類放在'akka.actor'包中時纔有效,這是一種黑客攻擊。看[這個答案](http://stackoverflow.com/a/26723452/843660)。不知道Java可以做什麼。 – dskrvk