【问题标题】:CDI Injection and serializationCDI 注入和序列化
【发布时间】:2012-06-28 00:46:03
【问题描述】:

我正在考虑为 slf4j 记录器使用 CDI 注入,所以我创建了一个生产者。

我将它注入一个可序列化的ApplicationScoped bean:

@ApplicationScoped
public final class CurrentApplicationBean implements Serializable {
    @Inject
    private transient Logger          logger;
}

它必须是瞬态的,因为org.slf4j.Logger 是一个不扩展Serializable 的接口,但这意味着必须在反序列化后重新注入记录器。

我认为 CDI 无法处理这个问题,你知道吗?

此外,提供者总是提供一个新的Logger 实例,因为它必须从InjectionPoint 设置记录器名称,这意味着RequestScoped bean 有自己的记录器实例,而不是每个类的静态记录器。

也许日志记录不是 CDI 注入的好上下文...您有什么考虑?

【问题讨论】:

  • 虽然 org.slf4j.Logger 出于向后兼容性的原因未标记为可序列化,但 org.slf4j.Logger 的大多数(如果不是全部)实际实现都是可序列化的。另请参阅glauche.de/2009/08/24
  • >>我认为 CDI 不处理这个问题,你知道什么不,它没有。 >>也许日志记录不是 CDI 注入的好上下文 这是一个很好的上下文 :) 你的原始代码应该在编译时出现警告,你应该没问题

标签: logging cdi code-injection


【解决方案1】:

但这意味着必须在反序列化后重新注入记录器。

CDI 容器代理是可序列化的。反序列化时,代理会定位/绑定到正确的注入。我不会将注入点标记为瞬态;因为这会阻止容器定位/重新绑定注入并导致 NPE。

这意味着 RequestScoped bean 有自己的记录器实例,而不是每个类的静态记录器

如果你的生产者方法是这样的

@RequestScoped
@Produces   
public Logger produceLog(InjectionPoint injectionPoint) {   
    return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass().getName());   
}

LoggerFactory.getLogger() 为每个类创建一个记录器。

也许日志记录不是 CDI 注入的好上下文...您有什么考虑?

这是你的选择。

【讨论】:

  • CDI 代理是可序列化的。但是,当尝试将不可序列化的类注入到可能被钝化的 CDI bean 中时,您将在启动时遇到异常:“无法生成不可序列化的实例以注入到钝化 bean 的非瞬态字段中”。所以这里的建议是将该字段标记为瞬态,这实际上会在钝化/激活后引起问题。
猜你喜欢
  • 2016-01-11
  • 2017-10-25
  • 1970-01-01
  • 2011-03-06
  • 2016-06-07
  • 2023-03-10
  • 2015-02-12
  • 2013-09-17
  • 1970-01-01
相关资源
最近更新 更多