Spring添加对缓存的支持

缓存可以可以存储经常使用到的信息,如果这些信息保存在数据库中,经常对数据库的读取会严重影响应用的性能,所以将这些信息保存在缓存中,取出来就可以立即使用。

1、启用spring对缓存的支持

Spring对缓存的支持有两种方式:

1)注解驱动缓存

2)XML申明的缓存

使用Spring最通用的方法就是在方法上添加@Cacheable和@CacheEvict注解。本人更喜欢使用XML与注解混合使用的方式开发。

2、使用XML文件配置缓存

<?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:cache="http://www.springframework.org/schema/cache"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/cache
        http://www.springframework.org/schema/cache/spring-cache-3.2.xsd
        http://www.springframework.org/schema/context   
        http://www.springframework.org/schema/context/spring-context-3.1.xsd">

  <!-- 启用缓存注解开关 -->
  <cache:annotation-driven cache-manager="cacheManager"/>
  <!-- 启用注解 -->
  <context:component-scan base-package="com.zjp" />
  <context:annotation-config/>

  <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="configLocation" value="classpath:ehcache.xml"/>
  </bean>

  <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
    <property name="cacheManager" ref="ehcache"/>
  </bean>

</beans>

在spring配置文件中声明了使用ehcache缓存管理器以及对应的ehcache.xml文件定义的缓存。
对应的ehcache.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">

  <!-- 磁盘缓存位置 -->
  <diskStore path="java.io.tmpdir/ehcache"/>

  <!-- 默认缓存 -->
  <defaultCache
          maxEntriesLocalHeap="10000"
          eternal="false"
          timeToIdleSeconds="120"
          timeToLiveSeconds="120"
          maxEntriesLocalDisk="10000000"
          diskExpiryThreadIntervalSeconds="120"
          memoryStoreEvictionPolicy="LRU">
    <persistence strategy="localTempSwap"/>
  </defaultCache>

  <cache name="userCache"
         maxElementsInMemory="1000"
         eternal="false"
         timeToIdleSeconds="3"
         timeToLiveSeconds="3"
         maxEntriesLocalDisk="10000000"
         overflowToDisk="false"
         memoryStoreEvictionPolicy="LRU"/>
  <cache name="users"
         maxElementsInMemory="1000"
         eternal="false"
         timeToIdleSeconds="3"
         timeToLiveSeconds="3"
         maxEntriesLocalDisk="10000000"
         overflowToDisk="false"
         memoryStoreEvictionPolicy="LRU"/>
</ehcache>

其中定义了两个缓存,分别为userCache和users。

3、为对应的方法添加注解支持缓存

为对应的方法添加上注解就可以实现对缓存的控制,常用的注解如下:

注解 作用
@Cacheable 添加缓存之前检查缓存中是否存在,存在就不调用,否则调用
@CachePut 不管缓存是否存在都调用方法
@CacheEvict 删除一条或者多条缓存
@Caching 分组的注解,可以同时应用多个缓存注解

1)添加缓存

@Cacheable和@CachePut注解都可以填充缓存,但是它们的工作方差异。
@Cacheable首先在缓存中查找条目,如果找到了匹配的条目,那么就不会对方法进行
了。如果没有找到匹配的条目,方法会被调用并且返回值要放到缓存之中。而@Cache
不会在缓存中检查匹配的值,目标方法总是会被调用,并将返回值添加到缓存之中。
a、自定义缓存key
@Cacheable和@CachePut都有一个名为key属性,这个属性能够替换默认的key,它是通过
一个SpEL表达式计算得到的。任意的SpEL表达式都是可行的,但是更常见的场景是所定义的
表达式与存储在缓存中的值有关,据此计算得到key。

 @CachePut(value = "users", key = "#user.getId()")
    public void updateUser(User user) {
        userDao.updateUser(user);
    }

b、条件化缓存
@Cacheable和@CachePut提供了两个属性用以实现条件化缓存:unless和condition,
这两个属性都接受一个SpEL表达式。如果unless属性的SpEL表达式计算结果为true,那么
缓存方法返回的数据就不会放到缓存中。与之类似,如果condition属性的SpEL表达式计算
结果为false,那么对于这个方法缓存就会被禁用掉。

 @Cacheable(value = "users", condition = "#user.getId() <= 2")// 当id>2的时候禁用缓存
    public User findUserInLimit(User user) {
        return userDao.findUserById(user.getId());
    }

2)缓存的移除

使用@CacheEvict 就可以移除缓存中对应的数据。
对于缓存操作的UserService如下:

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    @Cacheable({"users"})
    public User findUser(User user) {
        System.out.println("userDao--"+userDao);
        User findUserById = userDao.findUserById(user.getId());//数据库
        System.out.println("user---"+findUserById);
        return userDao.findUserById(user.getId());//数据库
    }

    @Cacheable(value = "users", condition = "#user.getId() <= 2")// 当id>2的时候禁用缓存
    public User findUserInLimit(User user) {
        return userDao.findUserById(user.getId());
    }

    @CachePut(value = "users", key = "#user.getId()")
    public void updateUser(User user) {
        userDao.updateUser(user);
    }

    @CacheEvict(value = "users")
    public void removeUser(User user) {
        userDao.removeUserById(user.getId());
    }

    @CacheEvict(value = "users", allEntries = true)
    public void clear() {
        userDao.removeAllUser();
    }
}   

同时添加上其他的


public interface UserDao {

    /**
     * 删除所有用户
     */
    public void removeAllUser();
    /**
     * 根据Id查询用户
     * @param id
     * @return
     */
    public User findUserById(long id);
    /**
     * 更新用户
     * @param user
     */
    public void updateUser(User user);
    /**
     * 根据Id删除用户
     * @param id
     */
    public void removeUserById(long id);

}
package com.zjp.service.impl;

import org.springframework.stereotype.Service;

import com.zjp.domain.User;
import com.zjp.service.UserDao;

@Service
public class UserDaoImpl implements UserDao{

    public void removeAllUser() {
        // TODO Auto-generated method stub

    }

    public User findUserById(long id) {
        User user = new User();
        user.setId(123424);
        user.setPassword("ahfakjbnfjk");
        user.setUsername("lisi");
        return user;
    }

    public void updateUser(User user) {
        // TODO Auto-generated method stub

    }

    public void removeUserById(long id) {
        // TODO Auto-generated method stub

    }

}

猜你喜欢

转载自blog.csdn.net/chenfengdejuanlian/article/details/73498346