Jak ustawić cacheControlMappings w WebContentInterceptor w Spring 5 Xml

Aug 24 2020

Chcę dodać dyrektywę kontroli pamięci podręcznej (ustawić zarówno publiczne, jak i maksymalne sekundy) dla kilku adresów URL w Spring MVC i chcę wprowadzić te zmiany tylko za pośrednictwem applicationContext.xml.

Próbuję ustawić właściwość mapę cacheControlMappingsz org.springframework.web.servlet.mvc.WebContentInterceptor, ale jedynym problemem jest projektowanie klasy, która nie ma metody setter dla nieruchomości. Aby obejść ten problem, wywołuję addCacheMappingmetodę przy użyciu org.springframework.beans.factory.config.MethodInvokingBean.

Moja konfiguracja w spring-mvc-config.xml jest następująca - tworzę CacheControlbean w następujący sposób i sprawdziłem przez debugowanie, czy ten bean został pomyślnie utworzony z odpowiednimi wartościami wypełnionymi w kontekście aplikacji.

<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>

Następnie chcę wywołać tej metody - public void addCacheMapping(CacheControl cacheControl, String... paths)z WebContentInterceptorktórych będą dodawać wpisy na mapie cacheControlMappings.

Sprawdziłem, że wywołanie tej metody programowo działa świetnie, więc powinno działać dobrze, jeśli wywołam ją z XML, prawda? Ale próbuję zrobić to samo, co pokazano poniżej, ale to nie działa dla mnie i otrzymuję zero wpisów dodanych do ostatecznej mapy.

<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>

Dlaczego powyższe wywołanie MethodInvokingBeannie działa? Czy w jakikolwiek sposób ustawiam argumenty źle? Czy varargi wymagają innej obsługi? Nie widzę również żadnych błędów wyświetlanych podczas uruchamiania serwera.

Jestem również świadomy tego wątku SO ( jak ustawić kontrolę pamięci podręcznej: prywatna z applicationContext.xml w wersji Spring 4.2 lub nowszej ), w którym przyjęta odpowiedź wspomina, że ​​nie można tego zrobić w samym XML. Chciałem ponownie potwierdzić, czy jest to poprawne, próbując wdrożyć powyższe rozwiązanie, ale nie działa, ale nie rozumiem dlaczego.

Odpowiedzi

Anurag Aug 25 2020 at 04:52

Tak jak podejrzewałem, wystąpił problem ze sposobem, w jaki argumenty zaczęły się pojawiać. Wartości vararg we wstrzyknięciu sprężyny muszą być podane jako jawna lista zamiast przeciążenia argumentów (tak jak w Javie).

Zatem poprawny sposób wywołania takiej metody -

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

wiosną applicationContext.xml wygląda następująco -

<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>

Jak widać, użyłem teraz MethodInvokingFactoryBean. Jakoś mi MethodInvokingBeannie wyszło .