需要能够将@Inject Serializable设置为@SessionScoped bean

时间:2013-08-11 15:41:43

标签: serialization cdi suppress-warnings

我有一个生产者方法想要生成一个不可修改的集合:

// EnumSet.noneof returns an object of type Serializable, and also
// Collections#synchronizedSet javadoc says, "The returned set will be 
// serializable if the specified set is serializable."
private final Set<Role> roles =
      Collections.synchronizedSet(EnumSet.noneOf(Role.class));

...

@Produces @LoggedIn public Set<Role> getRoles()
{
    // Collections#unmodifiableSet javadoc also says, "The returned set will be
    // serializable if the specified set is serializable."
    return Collections.unmodifiableSet(this.roles);
}

我想将集合注入会话范围的bean:

@Inject @LoggedIn Set<Role> roles;

在注入点发出警告,说我不能将一个不可序列化的集合注入到钝化范围的bean中。警告是有意义的,因为Set接口不会扩展Serializable。然而,在这种情况下,根据javadoc,似乎roles实际上是可序列化的。我不确定处理这种情况的最佳方法是为了避免警告。

顺便提一下,我注意到在注入点应用@SuppressWarnings({"NonSerializableFieldInSerializableClass"})并不会抑制警告。但是我还注意到,位于注入点旁边的同一会话范围bean中的以下代码行不会导致发出警告消息:

@Inject @LoggedIn Set<Role> roles;  // warning
private Set<Role> roles1;           // no warning!

怪异!

我有三个问题:

  1. 在这种情况下,最好的方法是什么?

  2. 为什么@Inject @LoggedIn Set<Role> roles会引发警告,而private Set<Role> roles1却没有?

  3. 为什么在注入点应用@SuppressWarnings({"NonSerializableFieldInSerializableClass"})不会抑制警告?

1 个答案:

答案 0 :(得分:1)

只有第一行是注入点,因此CDI会扫描它并确保它可以注入。 CDI不会扫描第二行以确保它是可注射的,因为CDI不会尝试注入它。

SuppressWarnings是编译时注释,而不是运行时。它在编译的类中丢失了。

您可以创建一个实现可序列化的Set实现并使用它。它应该按照设定的方式注入。