如何在Spring 5 Xml中的WebContentInterceptor中设置cacheControlMappings

问题描述

我想为Spring MVC中的几个URL添加cache-control指令(同时设置公共和最大使用时间),我想仅通过applicationContext.xml进行这些更改。

我正在尝试设置cacheControlMappings的地图属性org.springframework.web.servlet.mvc.WebContentInterceptor,但是唯一的问题是没有该属性的setter方法的类的设计。解决方法是,我使用addCacheMapping调用org.springframework.beans.factory.config.MethodInvokingBean方法

spring-mvc-config.xml中的配置如下- 我正在按以下方式创建一个CacheControl bean,并通过调试进行了验证:是否已使用在应用程序上下文中填充的适当值成功创建了该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线程(How to set Cache-control: private with applicationContext.xml in Spring 4.2 or later)在接受的答案中提到,在XML本身中无法执行此操作。我想通过尝试实施上述解决方案来再次确认这是否正确,但是它不起作用,但我不知道为什么。

解决方法

正如我所怀疑的,论点的填充方式存在问题。弹簧注入中的varargs必须作为一个显式列表给出,而不是像在Java中那样重载参数。

所以调用这种方法的正确方法-

public void addCacheMapping(CacheControl cacheControl,String... paths)
春季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>

如您所见,我现在已经使用MethodInvokingFactoryBeanMethodInvokingBean不知怎么对我不起作用。