Cómo configurar cacheControlMappings en WebContentInterceptor en Spring 5 Xml
Quiero agregar la directiva de control de caché (establecer segundos públicos y de edad máxima) para un par de URL en Spring MVC y quiero hacer esos cambios solo a través de applicationContext.xml.
Estoy tratando de establecer la propiedad cacheControlMappingsdel mapa org.springframework.web.servlet.mvc.WebContentInterceptor, pero el único problema es el diseño de la clase que no tiene un método de establecimiento para la propiedad. Como solución alternativa, estoy invocando el addCacheMappingmétodo utilizando org.springframework.beans.factory.config.MethodInvokingBean.
Mi configuración en spring-mvc-config.xml es la siguiente: estoy creando un CacheControlbean de la siguiente manera, y verifiqué mediante la depuración que este bean se crea correctamente con los valores adecuados en el contexto de la aplicación.
<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>
Entonces deseo invocar este método, public void addCacheMapping(CacheControl cacheControl, String... paths)del WebContentInterceptorcual agregará entradas al mapa cacheControlMappings.
Verifiqué que llamar a este método mediante programación funciona muy bien, por lo que debería funcionar bien si lo invoco desde el XML, ¿verdad? Pero estoy tratando de hacer lo mismo, como se muestra a continuación, pero esto no funciona para mí, y no se agregan entradas al mapa final.
<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>
¿Por qué la invocación anterior MethodInvokingBeanno funciona? ¿Estoy estableciendo mal los argumentos de alguna manera? ¿Los varargs necesitan un manejo diferente? Tampoco veo ningún error durante el inicio del servidor.
Además, soy consciente de este hilo SO ( Cómo configurar el control de caché: privado con applicationContext.xml en Spring 4.2 o posterior ) donde la respuesta aceptada menciona que no hay forma de hacer esto en el XML mismo. Quería volver a confirmar si eso es correcto al intentar implementar la solución anterior, pero no funciona, pero no veo por qué.
Respuestas
Como sospechaba, había un problema en la forma en que se estaban poblando los argumentos. Los varargs en una inyección de primavera deben proporcionarse como una lista explícita en lugar de una sobrecarga de argumentos (como se hace en Java).
Entonces, la forma correcta de invocar tal método:
public void addCacheMapping(CacheControl cacheControl, String... paths)
en la primavera, applicationContext.xml es el siguiente:
<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>
Como puede ver, ahora he usado MethodInvokingFactoryBean. De alguna manera MethodInvokingBeanno funcionó para mí.