英文原文:
Spring 3.1 Caching and @Cacheable
在软件开发中使用缓存已经有一个非常久的历史了。缓存是一种很好的设计思想,一旦你用了他,你将会发现他确实很有用。Spring3.1版本的核心对缓存做了实现。在Java推出Annotation特性之前,实现缓存的一个难点在于它与业务逻辑代码的耦合性太强。
然而,Spring3.1中使用@Cacheable 和@CacheEvict实现缓存在某种程度上解决了这个问题,基本思想是在方法加上@Cacheable注解,这个方法的返回值将具有缓存特性。
@Cacheable注解可以用在方法或者类级别。当他应用于方法级别的时候,就是如上所说的缓存返回值了。当应用在类级别的时候,这个类的所有方法的返回值都将被缓存。
@Cacheable(value = "employee")
public class EmployeeDAO {
public Person findEmployee(String firstName, String surname, int age) {
return new Person(firstName, surname, age);
}
public Person findAnotherEmployee(String firstName, String surname, int age) {
return new Person(firstName, surname, age);
}
}
@Cacheable注解有三个参数,value是必须的,还有key和condition。第一个参数,也就是value指明了缓存将被存到什么地方。
@Cacheable(value = "employee")
public Person findEmployee(String firstName, String surname, int age) {
return new Person(firstName, surname, age);
}
上面的代码保证findEmployee的返回值Person对象将被存储在"employee"中。
上面的代码保证findEmployee的返回值Person对象将被存储在"employee"中。
任何存储在缓存中的数据为了高速访问都需要一个key。Spring默认使用被@Cacheable注解的方法的签名来作为key,当然你可以重写key,自定义key可以使用SpEL表达式。
<span style="font-size:14px;">@Cacheable(value = "employee", key = "#surname")</span> public Person findEmployeeBySurname(String firstName, String surname, int age) {
return new Person(firstName, surname, age);
}
在findEmployeeBySurname()的注解中"#surname"是一个SpEL表达式,他将使用findEmployeeBySurname()方法中的surname参数作为key。
@Cacheable的最后一个参数是condition(可选),同样的,也是引用一个SpEL表达式。但是这个参数将指明方法的返回结果是否被缓存。
@Cacheable(value = "employee", condition = "#age < 25")
public Person findEmployeeByAge(String firstName, String surname, int age) {
return new Person(firstName, surname, age);
}
上面的例子中,只有年龄小于25的时候才被缓存。
在快速看完了如何使用缓存后,我们接下来看看缓存带来的效果。
<a href="http://my.oschina.net/test45" target="_blank" rel="nofollow">@Test</a>
public void testCache() {
Person employee1 = instance.findEmployee("John", "Smith", 33);
Person employee2 = instance.findEmployee("John", "Smith", 33);
assertEquals(employee1, employee2);
}
上面的例子很简单,第一次调用findEmployee,findEmployee方 法将被执行,Spring将他的返回值一个person对象存入缓存。第二次调用findEmployee的时候findEmployee将不被执 行,Spring直接将缓存中的数据作为返回值返回。所以employee1 和employee2引用了同样的对象。
而下面的例子中,我们将年龄小于25作为缓存条件,就将得到不同的结果。 <a href="http://my.oschina.net/test45" target="_blank" rel="nofollow">@Test</a>
public void testCacheWithAgeAsCondition() {
Person employee1 = instance.findEmployeeByAge("John", "Smith", 33);
Person employee2 = instance.findEmployeeByAge("John", "Smith", 33);
assertEquals(employee1, employee2);
}
Spring将返回一个对象的引用,在我第一次创建调用findEmployeeBySurname(…)。这对于Sping不是一个问题
类似的必须要小心指创建的对象的方法应用到@Cachable条件注释。
在我的示例代码我应用了任意条件只有缓存的在25岁以下的Person实例。
@Test
public void testCacheWithAgeAsCondition() {
Person employee1 = instance.findEmployeeByAge("John", "Smith", 22);
Person employee2 = instance.findEmployeeByAge("John", "Smith", 22);
assertEquals(employee1, employee2);
}
上文仅仅是@Cacheable的使用方法,但是我们怎么使用@CacheEvict注解来清除缓存呢?另外,还有一个问题,如何选择一个缓存的实现,并配置Spring的缓存呢?欲知后事如何,且听下回分解。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
2KB翻译工作遵照
CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务