跳至主要内容

博文

目前显示的是标签为“Spring”的博文

Dev's Ranting - OnCommittedResponseWrapper in Spring

一转眼已经到了十月,我的草稿箱里还存着一个八月遇到的诡异bug:在我们的Spring Boot应用程序里,用到了Spring Security和Spring Session,这两个modules一直以来相安无事,直到有一天…… 使用Hibernate的时候如果查询结果集合过大,会导致response无法迅速返回。这里有两个要命的问题,首先由于Query在执行的时候JDBC的block调用过长,HTTP Gateway会超时;其次结果集过大意味着Hibernate在真正写入response (例如将结果集转换为DTO再写入CSV)之前不得不在内存中持有所有结果的对象引用,最终会致内存占用的问题,要么GC要么OutOfMemory。 为了解决在查询结果下载时遇到的问题,我们用到了`StatelessSession`和`ScrollableResult`来获取一个相当大的`ResultSet`,通过Java 8 的`Stream` 来访问单个元素,从而实现stream downloading。但是在调试中发现无法得到完整的CSV结果,经常是写到半当中就EOF了?! 同事老R花了大半天的时间来debug,最终无比惊讶的发现是Spring在控制`HttpServletResponse`的committed事件时有隐藏手段——`OnCommittedResponseWrapper`。貌似这个class在 [Spring Session](https://github.com/spring-projects/spring-session/blob/master/spring-session-core/src/main/java/org/springframework/session/web/http/OnCommittedResponseWrapper.java) 和 [Spring Security](https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/security/web/util/OnCommittedResponseWrapper.java) 内各自有一份copy,而且还并非完全一样。 /** * Imp...