繁体   English   中英

如何在 OSGi 中实现具有 class 的捆绑包,该捆绑包将值放入 ThreadContext 以使这些值对其他捆绑包可见

[英]How to implement in OSGi a bundle that has a class which puts values into ThreadContext to have these values be visible to other bundles

总结一下这个问题,我有一个常见的 class 在整个项目中使用的捆绑包中。 这个 class 是一个方面 class 将值放入 ThreadContext(log4j2) 以便我们的日志记录具有相应的 session 详细信息到日志中。

我发现 ThreadContext 像 ThreadLocal 变量一样工作。 由于 OSGi 对每个包都有不同的类加载器,因此 ThreadContext 值的调用者/用户根本无法看到这些值。

参考:

ThreadLocals 和并行类加载的影响 https://stackoverflow.com/a/34738856/8136561

我期望的是仍然有一个包含公共代码的包,但其他包仍然能够看到放入 ThreadContext 的值。 我不确定这是否可能。

编辑:添加示例代码

Bundle1(通用代码)

@Configurable
@Aspect
public class AspectLogger {

    @Before("within(@org.springframework.stereotype.Controller *)")
    public void beforeControllerAdvice(JoinPoint joinPoint) {
        Object[] paramValues = null;
        paramValues = joinPoint.getArgs();
        Object request = null;
        for (Object arg : paramValues) {
            if (arg instanceof RenderRequest) {
                request = arg;
            } else if (arg instanceof ResourceRequest) {
                request = arg;
            } else if (arg instanceof ActionRequest) {
                request = arg;
            }
        }

        if (request != null) {
            String transactionID = UUID.randomUUID().toString();
            ThreadContext.put("transactionID", transactionID);
        }
    }
}

Bundle 2,3...n(将此方面用作 Bean)

<bean id="aspectLogger" class="shared.bundle.common.AspectLogger" />

Log4j2 配置使用此值作为记录器附加程序(问题值在日志中为空)

<PatternLayout>
    <Pattern>%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %c{2} (%F:%L) [transactionID: %X{transactionID}] - %m%n</Pattern>
</PatternLayout>

从 Debugger 的角度来看,我可以看到控制器的线程和方面的线程基本相同。 但我仍然没有得到值,我什至在@Controller级别尝试了ThreadContext.get("transactionID")但它是空的。

所以问题的原因是 log4j 嵌入到每个 war 文件中,然后部署到 OSGi。 嵌入的类由各自的包加载。 所以他们生活在不同的类加载器中。

在 OSGi 中嵌入日志记录是一个坏主意。 原因之一是您无法拥有中央日志记录配置。 另一个原因是上面的问题。

您可以查看 pax-logging 或 felix logback 支持作为适当的 OSGi 日志记录解决方案。 两者都提供 log4j API。

然后,在您的war 文件中,您需要为日志记录 api 包定义导入。 然后所有的战争都应该使用来自同一个委托类加载器的 ThreadContext 并且问题应该得到解决。

ThreadLocals 和 class 加载器是正交的。 为每个包使用不同的 class 加载器并没有说明哪些线程可能正在调用从这些包加载的类。 因此只要在调用另一个包中的代码之前设置 ThreadLocal,该代码就可以看到线程的 ThreadLocals。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM