1. 程式人生 > >dubbo2.5-spring4-mybastis3.2-springmvc4-mongodb3.4-redis3.2整合(六)Spring中Redis的快取的使用

dubbo2.5-spring4-mybastis3.2-springmvc4-mongodb3.4-redis3.2整合(六)Spring中Redis的快取的使用

前面已經寫了四篇關於dubbo2.5-spring4-mybastis3.2-springmvc4-mongodb3.4-redis3.2整合的文章:

快取(Caching)可以儲存經常會用到的資訊,這樣每次需要的時候,這些資訊都可以立即可用的。儘管Spring自身並沒有實現快取的解決方案,但是他對快取功能提供了宣告式的支援,能夠與各種流行的快取進行整合。幾天主要介紹的是redis的快取的支援。

1. Spring中啟用對快取管理的支援

Spring中對快取管理器的支援有兩種方式:

  • 註解驅動的快取
  • XML宣告的快取

1.1 註解驅動的快取

使用Spring的快取抽象時,最為通用的方式就是在方法上新增@Cacheable和@CacheEvict註解。

在往bean新增快取註解之前,必須要啟用Spring對註解驅動的支援。如果我們使用java配置的話,那麼可以在其中一個配置上新增@EnableCaching,這樣的話就能啟動註解驅動的快取。

package com.lidong.util;


import java.lang.reflect.Method;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import
org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.core.RedisTemplate; @Configuration
@EnableCaching public class CachingConfig extends CachingConfigurerSupport{ @Bean public KeyGenerator wiselyKeyGenerator(){ return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); } }; } /** * 宣告快取管理器 * @param redisTemplate * @return */ @Bean public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) { return new RedisCacheManager(redisTemplate); } }
1.2 XML宣告的快取

如果以XML的方式配置應用的話,那麼可以是使用Spring cache名稱空間的

<cache:annotation-driven/>

元素來啟動註解驅動的快取。

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.0.xsd">
    <!--啟用快取-->
    <cache:annotation-driven/>  
     <!--宣告快取管理器-->
    <bean    id="org.springframework.data.redis.cache.RedisCacheManager"/> 

  </beans>

2. Spring中配置快取管理器

Spring 3.1內建了五個快取管理器

  • SimpleCacheManager
  • NoOpCacheManager
  • ConcrrentMapCacheManager
  • CompositeCacheManager
  • EhCacheCacheManager

Spring 3.2引入了另外的一個快取管理器,這個快取管理器可以在基於JCache(JSR-107)的快取提供商之中。除了核心的Spring框架,Spring data又提供了兩個快取管理器。
- RedisCacheManager 來自於Spring-data-redis專案
- GemfireCacheManager 來自於Spring-data-GemFire專案

所以我們選擇快取管理器時候,取決於使用底層快取供應商。

3. Spring中配置Redis快取管理器

快取的條目不過就是一個鍵值對(key-vlaue),其中key描述了產生value的操作和引數。因此你,Redis作為key-value儲存,非常適合於做快取。
Redis可以用來為spring快取抽象機制儲存快取條目,Spring-data-redis提供了RedisCacheManager,這是CacheManager的一個實現。RedisCacheManager 會與一個Redis伺服器協作,並且通過RedisTemplate將快取條目儲存到Redis中。

@Configuration
@EnableCaching
public class RedisCachingConfig extends CachingConfigurerSupport{

    @Bean  
    public KeyGenerator wiselyKeyGenerator(){  
        return new KeyGenerator() {

            @Override
            public Object generate(Object target, Method method,
                    Object... params) {
                StringBuilder sb = new StringBuilder();  
                sb.append(target.getClass().getName());  
                sb.append(method.getName());  
                for (Object obj : params) {  
                    sb.append(obj.toString());  
                }  
                return sb.toString(); 
            }  

        };  

    }  


    /**
     * 宣告快取管理器RedisCacheManager
     * @param redisTemplate
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) {
        return new RedisCacheManager(redisTemplate);
    }
}

4. 為方法添加註解以支援快取

Spring 的快取抽象在很大程度上是圍繞切面的構建的。在Spring中啟用快取時,會建立一個切面,它觸發一個或更多的Spring的快取註解。

Spring中提供了四個註解來宣告快取規則

  • @Cacheable 宣告Spring在呼叫方法之前,首先應該在快取中查詢方法的返回值。如果這個值能夠找到,就會返回儲存的值,否則的話,這個方法就會被呼叫,返回值會放在快取之中。
  • @CachePut 表明Spring應該將方法的返回值放到快取中,在方法的呼叫前並不會檢查快取,方法始終都會被呼叫
  • @CacheEvict表明Spring應該在快取中清除一個或多個條目
  • @Caching 這是一個分組的註解,能夠同時應用多個其他的快取註解

在Service層快取資料的資料

package com.lidong.core.user.service;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.lidong.api.service.user.IUserService;
import com.lidong.core.user.dao.IUserDao;
import com.lidong.model.user.User;
@Service("userService")
public class UserServiceImp implements IUserService {

    @Resource
    IUserDao mIUserDao;

    @Override
    public String sayHello(String name) {
          return "Hello " + name;  
    }
    @Cacheable(value={"getUserById"})
    @Override
    public User getUserById(int userId) {
        return mIUserDao.selectByPrimaryKey(userId);
    }

    @Override
    public User getUserByUsername(String username) {
        return mIUserDao.selectByPrimaryUsername(username);
    }

    @CacheEvict(value={"getAllUser"},allEntries=true)
    @Override
    public void addUser(User user) {
        mIUserDao.insert(user);
    }

    @Cacheable(value={"getAllUser"})
    @Override
    public List<User> getAllUser() {
        return mIUserDao.selectAllUsers();
    }

    @CacheEvict(value={"getAllUser","getUserById"},allEntries=true)
    @Override
    public int delUserById(Integer userId) {
        return mIUserDao.deleteByPrimaryKey(userId);
    }

    @CacheEvict(value={"getAllUser","getUserById"},allEntries=true)
    @Override
    public int updateUser(User user) {
        return mIUserDao.updateByPrimaryKey(user);
    }

}

資料快取成功

這裡寫圖片描述

再次獲取使用者列表的時候;直接從快取中讀取使用者的列表。

注意:快取java物件時必須實現Serilaizable介面,因為Spring會將物件先序列化之後再存入到Redis中。

程式碼地址