Есть ли способ кэшировать файлы Spring ‹mvc:resources› в памяти?

Предположим, я связал все URL-адреса с сервлетом диспетчера Spring и установил некоторые каталоги .css и .js с <mvc:resources> в пространстве имен mvc Spring.

Могу ли я кэшировать эти статические ресурсы Spring в памяти, чтобы избежать обращения к диску по запросу пользователя?

(Обратите внимание, что я не спрашиваю о кэшировании HTTP, таком как ответ Not Modified, а также не имею в виду кэширование статических файлов Tomcat или настройку другого веб-сервера перед веб-сервером Java, просто решение Spring)


person Piotr Müller    schedule 01.04.2014    source источник
comment
cache-period не отвечает на ваш вопрос?   -  person Artem Bilan    schedule 01.04.2014
comment
@ArtemBilan Насколько я знаю, это связано с дальнейшим запросом клиента и ответом HTTP (не измененным), но если новый клиент хочет загрузить файлы (посещает страницу), то происходит чтение с диска.   -  person Piotr Müller    schedule 01.04.2014


Ответы (1)


Что ж, поскольку вы говорите, что хотите cache всего содержимого вашего базового целевого ресурса, вы должны кэшировать его byte[] из inputStream.

Поскольку <mvc:resources> поддерживается ResourceHttpRequestHandler, нет никаких ограничений для написания собственного подкласса и использования его напрямую вместо этого пользовательского тега.

И реализуйте свою логику кэширования только в переопределенном методе writeContent:

public class CacheableResourceHttpRequestHandler extends ResourceHttpRequestHandler {

        private Map<URL, byte[]> cache = new HashMap<URL, byte[]>();

        @Override
        protected void writeContent(HttpServletResponse response, Resource resource) throws IOException {
            byte[] content = this.cache.get(resource.getURL());
            if (content == null) {
                content = StreamUtils.copyToByteArray(resource.getInputStream());
                this.cache.put(resource.getURL(), content);
            }
            StreamUtils.copy(content, response.getOutputStream());
        }

    }

И используйте его из конфигурации spring в качестве универсального компонента:

<bean id="staticResources" class="com.my.proj.web.CacheableResourceHttpRequestHandler">
    <property name="locations" value="/public-resources/"/>
</bean>

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <value>/resources/**=staticResources</value>
    </property>
</bean>
person Artem Bilan    schedule 01.04.2014