【问题标题】:Spring annotation based caching基于 Spring 注解的缓存
【发布时间】: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()的代码吗?

标签: java spring


【解决方案1】:

在您的 servlet-controller.xml 中,您在执行 context:component-scan 时不排除 @Component bean

<context:component-scan base-package="com.myapp.test">
    <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
  </context:component-scan>

你应该添加use-default-filters="false"

 <context:component-scan base-package="com.myapp.test" use-default-filters="false">
        <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
  </context:component-scan>

避免 bean 阴影。

【讨论】:

  • 谢谢,我确认这确实是问题所在。由于默认过滤器设置,该 bean 被 servlet-context.xml 扫描。
猜你喜欢
  • 1970-01-01
  • 2015-04-09
  • 2015-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-02
  • 2015-05-14
  • 1970-01-01
相关资源
最近更新 更多