【问题标题】:Transient fields in Spring session-scoped controllerSpring会话范围控制器中的瞬态字段
【发布时间】:2012-09-21 11:23:37
【问题描述】:

我有一个设置为会话范围的 Spring 控制器 bean,它看起来有点像这样:

@Controller
@Scope(WebApplicationContext.SCOPE_SESSION)
@RequestMapping("/test")
public class SessionTestController implements Serializable {

    private static final long serialVersionUID = -7735095657091576437L;

    private transient Log log;

    @PostConstruct
    public void initialise() {
        log = LogFactory.getLog(getClass());
    }

    @RequestMapping(method=RequestMethod.GET)
    @ResponseBody
    public String doGet() throws InterruptedException {
        log.warn("This line will fail after deserialisation..."); // Causes NPE
    }

}

似乎 Spring 在反序列化后没有调用 @PostConstruct,这导致我的“日志”字段变为 null 并在我的 doGet() 方法中抛出 NullPointerException。

您通常如何处理非序列化字段,例如会话范围 bean 中的记录器?我是否需要实现一些会话感知接口才能完成这项工作?

【问题讨论】:

    标签: spring session logging spring-3


    【解决方案1】:

    我认为一个典型的方式是使用readObject()来初始化transient字段,不管是不是Spring bean:

    private void readObject(ObjectInputStream stream)
         throws IOException, ClassNotFoundException {
        stream.defaultReadObject();
        initializeTransientFields();
    }
    

    【讨论】:

    • 我认为我在这次@PostConstruct 尝试中走上了一条糟糕的道路。我希望这是正确的解决方案。
    • 在我的示例中,我将记录器设为静态并修复了类名参数LogFactory.getLog(SessionTestController.class);,但我的其他一些字段现在使用readObject。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    相关资源
    最近更新 更多