EJB3 идентификатор корреляции
-
27-10-2019 - |
Вопрос
Теперь мои коллеги работают над подсистемой регистрации, и они хотят связать отдельные операции, которые были инициированы из -за некоторого бизнес -метода. Например, если метод из Bean A вызовы к какому -либо методу в Bean B, а затем в Bean C будет здорово знать, чем бизнес -методы в Bean B и Bean C, выполняет несколько сотрудников для метода из Bean A. Особенно это будет здорово для Знайте, что методы из B и C проделали некоторую единицу работы для бетонного вызова Бона А.
Итак, вопрос в том, как связать эти единицы работы во что -то всего? Очевидно, что не красиво использовать аргументы метода для привязки!
А также я думаю, что пришло время задать другой вопрос, который достаточно близок к предыдущему. Что если я хочу распространить некоторую контекстную информацию от бобов А до другой бобы, которые называются из А? Что -то вроде учетных данных безопасности и принципала безопасности? Что я могу сделать? Может быть, вопросы, которые я задал, - это какая -то плохая практика?
Решение
Выглядит как хороший вариант использования для MDC, доступен в обоих Заготовить а также Log4j. Анкет По сути, вы прикрепляете какое -то пользовательское значение к потоку, и все сообщения журнала, подходящие от этого потока, могут прикрепить это значение к сообщению.
Я думаю, что лучший способ реализовать это в EJB будет перехватчик:
public class MdcInterceptor {
@AroundInvoke
public Object addMdcValue(InvocationContext context) throws Exception {
MDC.put("cid", RandomStringUtils.randomAlphanumeric(16));
try {
return context.proceed();
} finaly {
MDC.remove("cid");
}
}
}
Теперь все, что вам нужно сделать, это добавить:
%X{user}
к вашему схеме ведения журнала (logback.xml
или же log4j.xml
).
Смотрите также
Другие советы
Для контекстной информации общего назначения вы можете использовать TransactionSynchronizationRegistry. Анкет Это может выглядеть примерно так:
@Stateless
public class MyBean {
@Resource
TransactionSynchronizationRegistry registry;
@AroundInvoke
public Object setEntryName(InvocationContext ic) throws Exception {
registry.putResource(NAME, "MyBean");
return ic.proceed();
}
}
@Stateless
public class MyBean2 {
@Resource
TransactionSynchronizationRegistry registry;
public void doJob() {
String entryName = (String)registry.getResource(NAME);
...
}
}
Я считаю, что это обычно реализуется с помощью Threadlocal Переменные, как обычно, каждая транзакция отображает в потоке сигле на серверах приложений. Таким образом, если TransactionSynchronization Registry не реализована в вашем AS (например, в JBoss 4.2.3) или вам нужен инструмент более низкого уровня, вы можете напрямую использовать нитокальные переменные.
Кстати, я думаю, что утилиты MDC используют то же самое под обложками.