我想创建一个生成器,它可以将java.util.ResourceBundle注入到任何类中,以便轻松获得本地化的字符串。我的ResourceBundle-Producer看起来像这样:
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不可序列化。
发布于 2010-07-17 14:55:44
首先,ResourceBundle 不是可序列化的。参见here。信息是明确的
无法生成non-serializable实例以注入到钝化beans的非瞬态字段中
钝化豆?我认为web.PersonHome要么是有状态会话bean,要么是@ConversationScoped Bean。我说的对吗?如果是这样的话,您应该用将您的包属性标记为瞬态
private transient @Inject ResourceBundle bundle;
发布于 2014-02-05 04:54:28
根据亚瑟接受的答案中的评论帖子。我跟随this blog和this one进行了一个钝化/激活实验。实验证明了MrD关于瞬态属性在激活时将为空的结论。因此,为了处理具有钝化能力的bean (即会话作用域、会话作用域和有状态会话bean)的非序列化成员属性,我建议使用以下解决方案:
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记录器,如下所示:
@Produces
@LogbackLogger
public Logger produceLogger(InjectionPoint injectionPoint){
return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
}
假设您声明了限定符:
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface LogbackLogger {
}
然后在支持钝化的bean中,按如下方式注入:
@Inject
@LogbackLogger
private Logger logger;
https://stackoverflow.com/questions/3000170
复制相似问题