4

现在我的同事正在研究日志子系统,他们想绑定从某种业务方法启动的单独操作。例如,如果 bean A 中的方法调用 bean B 中的某个方法,然后调用 bean C 中的某个方法,那么知道 bean B 中的业务方法和 bean C 为 bean A 中的方法做了一些工作人员会很棒。尤其是知道 B 和 C 的方法为 bean A 的具体调用做了一些工作单元。

那么,问题是如何将这些工作单元与整体联系起来?显然,使用方法参数进行绑定并不美观!

而且我认为是时候问另一个问题了,这个问题与前一个问题足够接近。如果我想将一些上下文信息从 bean A 传播到另一个从 A 调用的 bean,该怎么办?诸如安全凭证和安全主体之类的东西?我能做些什么?可能是我问的问题是某种不好的做法?

4

2 回答 2

3

看起来像是 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.xmllog4j.xml)。

也可以看看

于 2012-02-19T21:49:40.603 回答
0

For general purpose context information you can use TransactionSynchronizationRegistry. It could look something like this:

@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);
        ...
    }
}

I believe it is usually implemented using ThreadLocal variables as normally each transaction maps to a sigle thread in application servers. So if TransactionSynchronizationRegistry is not implemented in your AS (like e.g. in JBoss 4.2.3) or you need lower level tool, you could use ThreadLocal variables directly.

BTW I guess that MDC utilities use the same thing under the covers.

于 2012-02-21T14:04:23.810 回答