Spring的DI不是瞬态的,也不是可序列化的,而是Logs NSE

时间:2013-04-30 11:28:15

标签: spring dependency-injection deserialization

我有一个Session-Scope Bean LoginPlaintext,它不能是可序列化的。

我有一个必须可序列化的Session-Scope Bean LoginMD5Salted

两者共享不可序列化的接口Login(因为LoginPlaintext必须不可序列化)!

我的AppConfig.java看起来像这样:

public class AppConfig 
   ...
   Login loginData(ServletRequest request){
      if(request.getParameter('useMD5')!=null){
         return new LoginMD5Salted();
      }
      return new LoginPlaintext();
   }
}

我的PermissionBean .java看起来像这样:

public class PermissionBean implements Serializable{
    @Autowired
    Login loginData;
}

我的LoginPlaintext看起来像这样:

public class LoginPlaintext implements Login{
    String plainTextPassword;
    ....
}

我的LoginMD5Salted看起来像这样:

public class LoginMD5Salted implements Login, Serializable{
    private static final long serialVersionUID = 2742674005972067910L;
    // not sure Upcase/Lowcase
    String MD5PasswordSalted;
}

如果会话被序列化:bean LoginPlaintext将不会被持久化。如果对序列进行反序列化,则所有其他值都会反序列化,但LoginPlaintext的反序列化器会抛出NotSerializableException,确定。

如果会话被序列化:bean LoginMD5Salted将保持良好状态。如果对会话进行反序列化,则所有值都会被反序列化,即使是LoginMD5Salted也没有任何问题。 问题:

  1. 如何仅阻止课程LoginPlaintext的日志消息?
  2. 如果无法通过重新激活反序列化LoginPlaintext,是否会再次调用AppConfig的loginData()方法?

3 个答案:

答案 0 :(得分:1)

如果命令式不能实现可序列化,则可以使其可序列化并覆盖LoginPlaintext的序列化/反序列化方法以始终序列化/反序列化null。 从来没有这样做,但不应该太难。 见http://docs.oracle.com/javase/6/docs/api/java/io/Serializable.html

另一种解决方法是使用两种登录风格组成范围会话bean,并标记您不希望使用瞬态序列化的那种。

答案 1 :(得分:0)

您可以定义一个bean,其会话范围由两种风格组成,即可序列化和非可序列化的bean,而不是具有会话范围的两个bean。

这可能是你的PermissionBean。

将java关键字transient添加到LoginPlaintext属性中。如果我没有错,这将被视为你实现了我给你的第一个答案,即它不会序列化您的敏感数据,并在反序列化时返回null。

和前一个一样,我实际上并没有这样做,所以带上一粒盐

答案 2 :(得分:0)

我会说你为什么要在会话中存储LoginPlaintext?让loginData()返回要存储在Session中的值只是可序列化是没有意义的。如果要存储会话,存储在会话中的任何内容都应该是可序列化的。因此,要么不在会话中存储Login,要使Login成为暂时的,要么不允许LoginPlaintext实施Login