Spring是否使用缓存中的数据是通过方法参数(缓存的key)来判断的,往下看
在xml配置文件中导入cache命名空间
在xml配置文件中启用Spring缓存(一行)
<cache:annotation-driven cache-manager="缓存管理器的id"/>
所以接下来重要的任务就是配置缓存管理器(两种)
1.配置缓存管理器
1.1.Spring内置的缓存管理器配置(SimpleCacheManager)
SimpleCacheManager只是一种内存中的缓存,并非真正的缓存实现,不推荐在实际项目中使用
<!--使用SimpleCacheManager配置Spring内置的缓存管理器-->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<!--使用ConcurrentMapCacheFactoryBean配置多个缓存区-->
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
p:name="default"/>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
p:name="users"/>
</set>
</property>
</bean>
1.2.EhCache缓存实现的配置(EhCacheCacheManager)
需要的jar包
ehcache-2.10.5.jar
slf4j-api-1.7.25.jar
下载地址:http://d2zwv9pap9ylyd.cloudfront.net/ehcache-2.10.5-distribution.tar.gz
<!--缓存管理器需要配置CacheManager-->
<bean id="myCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cacheManager-ref="ehCacheManager"/>
<!--利用工厂来创建EhCacheManager-->
<!--p:configLocation指定缓存配置文件-->
<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:ehcache.xml"
p:shared="false"/>
ehcache.xml
<?xml version="1.0" encoding="utf-8"?>
<ehcache>
<!--表示硬盘上保存缓存的位置。默认使用临时文件夹。-->
<diskStore path="java.io.tmpdir"/>
<!-- 配置默认的缓存设置,如果类没有进行特别的设置,则使用此处配置的缓存属性。
maxElementsInMemory:设置缓存中最多可放多少个对象
eternal:设置缓存是否永久有效。
timeToIdleSeconds:设置缓存的对象多少秒没有被使用就会清理掉
timeToLiveSeconds:设置缓存的对象在过期之前可以缓存多少秒
overflowToDisk:设置缓存是否被持久化到硬盘中,保存路径由<diskStore.../>元素指定
-->
<defaultCache
maxElementsInMemory="1500"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="300"
overflowToDisk="true"/>
<!--也可以通过name设置针对某个类的缓存配置-->
<cache name="users1"
maxElementsInMemory="1000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
/>
<cache name="users2"
maxElementsInMemory="1000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
/>
</ehcache>
2.使用@Cacheable执行缓存
@Cacheable既可以修饰类也可以修饰方法,对应的作用域不同
@Cacheable可指定如下属性:
- value:必需属性,指定使用哪个缓存,指定对应的缓存名
- key:通过SpEL表达式显示指定缓存的key(指定参数,相等判断依据)
- condition:指定一个SpEL表达式,当为true时,才会执行缓存。
- unless:与condition相反,当为false时,才会执行缓存。
3.使用@CacheEvict清除缓存
@CacheEvict只能修饰方法,修饰后该方法用于清除缓存,方法体可以为空
@CacheEvict可指定如下属性
- value:必需属性,指定清除哪个缓存数据
- key:通过SpEL表达式显示指定缓存的key(指定参数,相等判断依据)
- allEntries:指定是否清空整个缓存区
- beforeInvocation:是否在执行方法前清除缓存(默认在执行方法之后清除缓存)
- condition:指定一个SpEL表达式,当为true时,才会清除缓存。
4.完整项目示例(使用EhCache)
项目结构:
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache
https://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--扫描service包及其自包下的所有bean-->
<context:component-scan base-package="com.lyx.service"/>
<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:ehcache.xml" p:shared="false"/>
<bean id="myCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cacheManager-ref="ehCacheManager"/>
<cache:annotation-driven cache-manager="myCacheManager"/>
</beans>
ehcache.xml
同上文ehcache.xml
User.java
public class User
{
private String name;
private Integer age;
public User(){}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
//省略getter,setter方法
}
UserService.java
public interface UserService
{
public User findUser(String name,Integer age);
public User deleteUser(String name, Integer age);
public void evictUsers1(String name,Integer age);
public void evictAll();
}
UserServiceImpl .java
@Service("userService")
@Cacheable(value = "users1",condition = "#age<8"/*,key = "#name"*/)
public class UserServiceImpl implements UserService
{
@Override
// @Cacheable(value = "users1")
public User findUser(String name, Integer age)
{
System.out.println("正在执行方法findUser:" + name + "--" + age);
return new User(name, age);
}
@Override
// @Cacheable(value = "users2")
public User deleteUser(String name, Integer age)
{
System.out.println("正在执行方法deleteUser:" + name + "--" + age);
return new User(name, age);
}
@Override
@CacheEvict("users1")
public void evictUsers1(String name, Integer age) {
System.out.println("正在清除缓存users1: " + name + "--" + age);
}
@Override
@CacheEvict(value = "users1",allEntries = true)
public void evictAll() {
System.out.println("正在清除所有缓存users1");
}
}
MyDriver.java
public class MyDriver
{
public static void main(String[] args) {
var ctx = new ClassPathXmlApplicationContext("beans.xml");
var us = (UserService)ctx.getBean("userService");
User u1 = us.findUser("张三",7);
// us.evictAll();
// us.evictUsers1("张三",7);
User u2 = us.deleteUser("张三",7);
System.out.println(u1==u2);
}
}