@RequestMapping("/getById") @ResponseBody @Cacheable public HugeValue getHugeValueFromSlowFoo( @RequestParam(value = "id",defaultValue = "") String id ) { return Foo.getById( id ); }
这工作正常,HugeValue对象存储在缓存中(在这种情况下为Hazelcast).我想进一步改进,因为从HugeValue创建JSON所花费的时间相当高.@H_404_5@我可以告诉spring cache来缓存JSON对象版本的对象吗?
我使用Jackson与Spring Boot 1.2和Spring 4.1
解决方法
据我所知,在SpringMVC中没有enableResponseBodyCaching功能.
第一个替代方法:使用http缓存,因为您似乎希望缓存整个http响应. Spring提供了一种直观的全局配置方式:
<mvc:interceptors> <bean id="webContentInterceptor" class="org.springframework.web.servlet.mvc.WebContentInterceptor"> <property name="cacheSeconds" value="0"/> <property name="useExpiresHeader" value="true"/> <property name="useCacheControlHeader" value="true"/> <property name="useCacheControlNoStore" value="true"/> </bean> </mvc:interceptors>
如果要控制每个控制器,继承自Spring AbstractController,并根据javaDoc设置cacheSeconds属性.
当然,http缓存的真正功能在您的服务器前面带有一个http代理.
第二个想法:实现你自己的MappingJackson2HttpMessageConverter子类.在writeInternal()中,您可以添加一些访问缓存的逻辑,以检索已经映射的版本,而不是映射输入对象.这种方法意味着您将打击您的服务以检索Json流后面的java对象.如果这对你来说很好,因为在某些时候也有缓存,这种做法值得一试.
第三个想法:在专用的包装器服务中自己做一个json映射,它提供了原始的json字符串/流.您可以轻松地注入杰克逊映射器(类名ObjectMapper)并获得对映射的完全控制.注释此服务,然后允许您缓存结果.在你的控制器中,你只提供一个你喜欢使用的类型的ResponseEntity(String或一些流).如果存在缓存结果,这甚至可以防止更深入的服务访问.
编辑:可能MappingJackson2JsonView也可以方便.说实话,我以前从来没有使用过它,所以我不能真正地说说它的用法.
希望有帮助和/或给予灵感!干杯