spring cache的使用 http://www.jianshu.com/p/49fc4065201a
Spring使用Cache(很详细) http://elim.iteye.com/blog/2123030
@Cacheable注解式缓存使用的要点:正确的注解式缓存配置,注解对象为spring管理的hean,调用者为另一个对象。有些情形下注解式缓存是不起作用的:同一个bean内部方法调用,子类调用父类中有缓存注解的方法等。后者不起作用是因为缓存切面必须走代理才有效,这时可以手动使用CacheManager来获得缓存效果。
<cache:annotation-driven/>有一个cache-manager属性用来指定当前所使用的CacheManager对应的bean的名称,默认是cacheManager,所以当我们的CacheManager的id为cacheManager时我们可以不指定该参数,否则就需要我们指定了。
<cache:annotation-driven/>还可以指定一个mode属性,可选值有proxy和aspectj。默认是使用proxy。
此外,<cache:annotation-driven/>还可以指定一个proxy-target-class属性,表示是否要代理class,默认为false。我们前面提到的@Cacheable、@cacheEvict等也可以标注在接口上,这对于基于接口的代理来说是没有什么问题的,但是需要注意的是当我们设置proxy-target-class为true或者mode为aspectj时,是直接基于class进行操作的,定义在接口上的@Cacheable等Cache注解不会被识别到,那对应的Spring Cache也不会起作用了。
使用注解式缓存的正确方式:
1 2 3 4 5 6 7 8 |
<cache:annotation-driven cache-manager="springCacheManager" proxy-target-class="false"/> <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="classpath:ehcache.xml"/> <property name="cacheManagerName" value="ehcache"/> </bean> <bean id="springCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> <property name="cacheManager" ref="ehcacheManager"/> </bean> |
要点:@Cacheable(value=”必须使用ehcache.xml已经定义好的缓存名称,否则会抛异常”)
1 2 3 4 5 |
@Cacheable(value = "employee", key = "#name") public int testCache(String name, String pwd, int age) { logger.debug("##### name=" + name + ",pwd=" + pwd + ",age=" + age); return age * 7; } |
基于AOP方式,跟上面一样效果
1 2 3 4 5 6 7 8 9 10 |
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> |
1 2 3 4 5 6 7 8 |
<cache:advice id="cacheAdvice" cache-manager="springCacheManager"> <cache:caching cache="employee2"> <cache:cacheable method="testCache2" key="#name"/> </cache:caching> </cache:advice> <aop:config proxy-target-class="false"> <aop:advisor advice-ref="cacheAdvice" pointcut="execution(* com.pandy..impl.TestService.*(..))"/> </aop:config> |
1 2 3 4 |
public int testCache2(String name, String pwd, int age) { logger.debug("##### name=" + name + ",pwd=" + pwd + ",age=" + age); return age * 7; } |
基于aspectj模式,测试失败,还没找到原因
1 |
<cache:annotation-driven mode="aspectj" cache-manager="springCacheManager" proxy-target-class="true"/> |
两个方法都缓存
1 2 3 4 5 6 7 8 9 |
<cache:advice id="cacheAdvice" cache-manager="springCacheManager"> <cache:caching cache="employee2"> <cache:cacheable method="testCache2" key="#name"/> <cache:cacheable method="call" key="#name"/> </cache:caching> </cache:advice> <aop:config proxy-target-class="false"> <aop:advisor advice-ref="cacheAdvice" pointcut="execution(* com.pandy..impl.TestService.*(..))"/> </aop:config> |
1 2 3 4 5 6 7 8 9 |
public int testCache2(String name, String pwd, int age) { logger.debug("##### name=" + name + ",pwd=" + pwd + ",age=" + age); return age * 7; } public int call(String name, String pwd, int age) { logger.debug("---------->call"); return testCache2( name, pwd, age); } |