【发布时间】:2014-02-07 06:33:17
【问题描述】:
我的 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 带注释的 beans
<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()的代码吗?