043Spring的缓存机制

本文介绍了Spring的缓存管理,包括如何配置SimpleCacheManager和EhCacheCacheManager,详细讲解了@Cacheable和@CacheEvict的使用,以及提供了一个完整的EhCache实战示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值