首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用Weld注入不可序列化的类(如java.util.ResourceBundle)

如何使用Weld注入不可序列化的类(如java.util.ResourceBundle)
EN

Stack Overflow用户
提问于 2010-06-09 02:30:33
回答 2查看 13.2K关注 0票数 21

我想创建一个生成器,它可以将java.util.ResourceBundle注入到任何类中,以便轻松获得本地化的字符串。我的ResourceBundle-Producer看起来像这样:

代码语言:javascript
复制
public class ResourceBundleProducer {
  @Inject       
  public Locale locale;

  @Inject       
  public FacesContext facesContext;

  @Produces
  public ResourceBundle getResourceBundle() {
    return ResourceBundle.getBundle("/messages", locale )
  }
}

Locale和FacesContext的注入起作用了(取自Seam3Alpha源代码的相应生成器)。但不幸的是,ResourceBundle是不可序列化的,因此不能以这种方式生成。当我试图访问一个调用使用我的ResourceBundle的bean的JSF页面时,我从Weld得到了以下错误:

Caused by: org.jboss.weld.IllegalProductException: WELD-000054 Producers cannot produce non-serializable instances for injection into non-transient fields of passivating beans\\n\\nProducer\: org.jboss.weld.bean-/D:/Program Files (x86)/GlassFish-Tools-Bundle-For-Eclipse-1.2/glassfishv3/glassfish/domains/teachernews/applications/teachernews/-ProducerMethod-services.producers.ResourceBundleProducer.getResourceBundle()\\nInjection Point\: field web.PersonHome.bundle

有什么方法可以让我的ResourceBundleResolver正常工作吗?或者,有没有其他机制来获得类似的功能?提前感谢!

编辑:

好的,我会花掉一些我辛苦获得的点数;)也会接受这个问题的一个很好的变通方法!

我有另一个创建生产者不起作用的例子: FlashProducer。也无法生成FacesContext-Flash,因为Flash不可序列化。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-07-17 14:55:44

首先,ResourceBundle 不是可序列化的。参见here。信息是明确的

无法生成non-serializable实例以注入到钝化beans的非瞬态字段中

钝化豆?我认为web.PersonHome要么是有状态会话bean,要么是@ConversationScoped Bean。我说的对吗?如果是这样的话,您应该用将您的包属性标记为瞬态

代码语言:javascript
复制
private transient @Inject ResourceBundle bundle;
票数 26
EN

Stack Overflow用户

发布于 2014-02-05 04:54:28

根据亚瑟接受的答案中的评论帖子。我跟随this blogthis one进行了一个钝化/激活实验。实验证明了MrD关于瞬态属性在激活时将为空的结论。因此,为了处理具有钝化能力的bean (即会话作用域、会话作用域和有状态会话bean)的非序列化成员属性,我建议使用以下解决方案:

代码语言:javascript
复制
private ResourceBundle bundle;

@PostConstruct
@PostActivate
public void getResourceBundle() {
    bundle = ResourceBundle.getBundle("/messages", locale );
}

此解决方案确保了不可序列化属性成员在每次进入就绪状态时都会重新初始化。

最后一个要解决的问题

要解决的最后一个问题是注入SLF4j记录器,它在slf4j 1.5.3和I quote之前是不可序列化的

从SLF4J版本1.5.3开始,记录器实例可以进行序列化。因此,主机类的序列化不再需要任何特殊操作,即使记录器被声明为实例变量也是如此。

因此,只要您的slf4j依赖项是1.5.3或更高版本,就可以安全地注入SLF4j记录器,如下所示:

代码语言:javascript
复制
@Produces
@LogbackLogger
public Logger produceLogger(InjectionPoint injectionPoint){
    return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
}

假设您声明了限定符:

代码语言:javascript
复制
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface LogbackLogger {
}

然后在支持钝化的bean中,按如下方式注入:

代码语言:javascript
复制
@Inject
@LogbackLogger
private Logger logger;
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3000170

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档