@Cachebale 不适用于 Ehcache 和 spring MVC Ehcache 不适用于 Spring Caching Annotation [英] @Cachebale not working with Ehcache and spring MVC Ehcache not working with Spring Caching Annotation
问题描述
我的应用程序是 Spring MVC 应用程序.尝试使用基于 Spring Annotation 的缓存.但它不起作用.请参考我下面的代码
My application is Spring MVC application. Tried using Spring Annotation based Caching. But it not working. Please refer my code below
1. pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.giggal.spring</groupId>
<artifactId>spring-tutorial-mvc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
......
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- EHCache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.2.2.21</version>
</dependency>
</dependencies>
</project>
2. My Spring app consists of two context xml config files, the first one app-ctx.xml only scans non-@Controller annotated beans:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<context:component-scan base-package="com.giggal.spring">
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation" />
</context:component-scan>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcache" />
</bean>
<bean id="ehcache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml" />
<property name="shared" value="true" />
</bean>
.....
</beans>
3. The second one mvc-config.xml contains all spring-mvc setup and scans @Controller annotated beans
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.giggal.spring" use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller"
type="annotation" />
</context:component-scan>
<mvc:annotation-driven />
<!-- 2. HandlerMapping : Used default handler mapping internally -->
<!-- 3. ViewResolver -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- Example: a logical view name of 'showMessage' is mapped to '/WEB-INF/jsp/showMessage.jsp' -->
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
4. The ehcache.xml used for caching with cache name emp :
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<defaultCache eternal="true" maxElementsInMemory="100"
overflowToDisk="false" />
<cache name="emp" maxElementsInMemory="10000" eternal="true"
overflowToDisk="false" />
</ehcache>
5. The controller class UserController
@Controller
@RequestMapping(value = "/user/")
public class UserController {
@Autowired
UserService userService; // Service which will do all data
// retrieval/manipulation work
@RequestMapping(value = "/getAllUsers/", method = RequestMethod.GET)
public ModelAndView listAllUsers() {
ModelAndView mav = new ModelAndView("user/user_list");
List<User> users = userService.findAllUsers();
mav.addObject("users", users);
return mav;
}
......
}
6. UserService class:
@Service("userService")
@Transactional
public class UserServiceImpl implements UserService {
private static final AtomicLong counter = new AtomicLong();
private static List<User> users;
static {
users = populateDummyUsers();
}
@Cacheable("emp")
public List<User> findAllUsers() {
System.out.println("execute getEmployee method..");
return users;
}
....
}
但是 findAllUsers() 方法调用永远不会被缓存,我每次总是得到 sysoutexecute getEmployee method..".什么可能导致这种情况?关于缓存注释,我肯定还有一些不明白的地方.
But the findAllUsers() method call never gets cached, I always get sysout "execute getEmployee method.." everytime. What may cause this? There's definitely something I don't yet understand about caching annotations.
But the same code is working as below
1.
@Configuration
@EnableCaching
@ComponentScan({ "com.giggal.*" })
public class AppConfig {
@Bean
public CacheManager cacheManager() {
return new EhCacheCacheManager(ehCacheCacheManager().getObject());
}
@Bean
public EhCacheManagerFactoryBean ehCacheCacheManager() {
EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean();
cmfb.setConfigLocation(new ClassPathResource("ehcache.xml"));
cmfb.setShared(true);
return cmfb;
}
}
---
@Controller
@RequestMapping(value = "/user/")
public class UserController {
@RequestMapping(value = "/getAllUsers/", method = RequestMethod.GET)
public ModelAndView listAllUsers() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(com.giggal.spring.AppConfig.class);
UserService obj = (UserService) context.getBean("userService");
List<User> users = obj.findAllUsers();
ModelAndView mav = new ModelAndView("user/user_list");
//List<User> users = userService.findAllUsers();
mav.addObject("users", users);
return mav;
}
..}
请建议使用注释的机制
推荐答案
在你的xml配置中,需要添加
In your xml configuration, you need to add
<cache:annotation-driven />
以便spring选择@Cacheable
注解.
so that spring pick @Cacheable
annotation.
See https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/cache/annotation/EnableCaching.html for more information.
@EnableCaching
和
负责注册必要的 Spring 组件注释驱动的缓存管理,例如 CacheInterceptor
和将拦截器编织成的基于代理或基于 AspectJ 的建议调用@Cacheable 方法时的调用堆栈.
@EnableCaching
and<cache:annotation-driven/>
are responsible for registering the necessary Spring components that power annotation-driven cache management, such as theCacheInterceptor
and the proxy- or AspectJ-based advice that weaves the interceptor into the call stack when @Cacheable methods are invoked.
这篇关于@Cachebale 不适用于 Ehcache 和 spring MVC Ehcache 不适用于 Spring Caching Annotation的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!