我的Spring应用由两个上下文XML配置文件组成,第一个是root-context.xml,只扫描非@Controller
注释的bean:
<beans ...>
<context:component-scan base-package="com.myapp.test">
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
</beans>
第二个servlet-context.xml文件包含所有Spring-MVC设置和扫描@Controller
注释的bean。
<beans:beans xmlns="http://www.springframework.org/schema/mvc" ...>
<annotation-driven />
<context:component-scan base-package="com.myapp.test">
<context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
...
</beans:beans>
web.xml中DispatcherServlet的配置如下:
<web-app ...>
...
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
...
</web-app>
我想尝试基于注解的缓存,因此我将以下bean定义添加到root-context.xml
<cache:annotation-driven/>
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="foo"/>
</set>
</property>
</bean>
请测试一下一个使用了@Service
注解的类,该类应该被root-context.xml扫描。
@Service
public FooService {
@Cacheable("foo")
public int getFoo() {
System.out.println("cache miss");
return new Random().nextInt(50);
}
}
但是getFoo()
方法调用从未被缓存,每次都会得到随机数。
然而,如果我在servlet-context.xml文件中扫描所有的bean并将缓存bean定义重新定位到那里,它就可以工作。
这是什么原因呢?显然,我还不理解缓存注解的某些内容。
getFoo()
的代码吗? - user180100