Как установить cacheControlMappings в WebContentInterceptor в Spring 5 Xml

Aug 24 2020

Я хочу добавить директиву управления кешем (установить как общедоступные, так и максимальные секунды) для пары URL-адресов в Spring MVC, и я хочу внести эти изменения только через applicationContext.xml.

Я пытаюсь установить свойство карты cacheControlMappingsиз org.springframework.web.servlet.mvc.WebContentInterceptor, но единственной проблемой является разработка класса , который не имеет присваиватель собственности. В качестве обходного пути я вызываю addCacheMappingметод с использованием org.springframework.beans.factory.config.MethodInvokingBean.

Моя конфигурация в spring-mvc-config.xml следующая: я создаю CacheControlbean-компонент следующим образом и проверил путем отладки, что этот bean-компонент успешно создан с соответствующими значениями, заполненными в контексте приложения.

<bean id="cacheControlFactory" class="org.springframework.http.CacheControl" factory-method="maxAge">
    <constructor-arg index="0" value="3600"/>
    <constructor-arg index="1">
        <value type="java.util.concurrent.TimeUnit">SECONDS</value>
    </constructor-arg>
</bean>

<bean id="myCacheControl" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject">
        <ref bean="cacheControlFactory"/>
    </property>
    <property name="targetMethod">
        <value>cachePublic</value>
    </property>
</bean>

Тогда я хочу , чтобы вызвать этот метод - public void addCacheMapping(CacheControl cacheControl, String... paths)из WebContentInterceptorкоторых будет добавлять записи на карту cacheControlMappings.

Я убедился, что программный вызов этого метода отлично работает, поэтому он должен работать нормально, если я вызываю его из XML, верно? Но я пытаюсь сделать то же самое, как показано ниже, но у меня это не работает, и я получаю ноль записей, добавленных в окончательную карту.

<bean class="org.springframework.beans.factory.config.MethodInvokingBean">
    <property name="targetObject">
        <ref bean="webContentInterceptor"/>
    </property>
    <property name="targetMethod">
        <value>addCacheMapping</value>
    </property>
    <property name="arguments">
        <list>
            <ref bean="myCacheControl" />
            <value>/home</value>
            <value>/dp/**</value>
            <value>/**/b/*</value>
        </list>
    </property>
</bean>

Почему вышеуказанный вызов MethodInvokingBeanне работает? Я каким-то образом неправильно формулирую аргументы? Нужна ли другая обработка вараргов? Я не вижу никаких ошибок при запуске сервера.

Кроме того, мне известно об этом потоке SO ( Как установить Cache-control: private с applicationContext.xml в Spring 4.2 или новее ), где в принятом ответе упоминается, что в самом XML нет способа сделать это. Я хотел еще раз подтвердить, правильно ли это, пытаясь реализовать вышеуказанное решение, но оно не работает, но я не понимаю, почему.

Ответы

Anurag Aug 25 2020 at 04:52

Как я и подозревал, возникла проблема в том, как аргументы приводились. Параметры varargs в Spring инъекции должны быть указаны как явный список, а не как перегрузка аргументов (как это сделано в Java).

Итак, правильный способ вызвать такой метод -

public void addCacheMapping(CacheControl cacheControl, String... paths)

в spring applicationContext.xml выглядит следующим образом -

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject">
        <ref bean="webContentInterceptor"/>
    </property>
    <property name="targetMethod">
        <value>addCacheMapping</value>
    </property>
    <property name="arguments">
        <list>
            <ref bean="myCacheControl" />
            <list>
                <value>/home</value>
                <value>/dp/**</value>
                <value>/**/b/*</value>
            </list>
        </list>
    </property>
</bean>

Как видите, я использовал MethodInvokingFactoryBean. Как-то MethodInvokingBeanу меня не вышло.