问题描述
我想为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>
如您所见,我现在已经使用MethodInvokingFactoryBean
。 MethodInvokingBean
不知怎么对我不起作用。