redisCacheManager

redisCacheManager(redis緩存管理器使用):配置+註解java

 

@Cacheable、@CachePut、@CacheEvict 註解介紹:redis

(1)@Cacheablespring

做用:主要針對方法配置,可以根據方法的請求參數對其結果進行緩存數據庫

@Cacheable 主要的參數:緩存

1)value:緩存的名稱,在 spring 配置文件中定義,必須指定至少一個mvc

例如:@Cacheable(value="mycache") 或者 @Cacheable(value={"cache1","cache2"})ui

2)key:緩存的 key,能夠爲空,若是指定要按照 SpEL 表達式編寫,若是不指定,則缺省按照方法的全部參數進行組合spa

例如:@Cacheable(value="testcache",key="#userName")code

3)condition:緩存的條件,能夠爲空,使用 SpEL 編寫,返回 true 或者 false,只有爲 true 才進行緩存component

例如:@Cacheable(value="testcache",condition="#userName.length()>2")

 

(2)@CachePut

做用:主要針對方法配置,可以根據方法的請求參數對其結果進行緩存,

 和@Cacheable不一樣的是,它每次都會觸發真實方法的調用

@CachePut 主要的參數:同@Cacheable

 

(3)@CacheEvict

做用:主要針對方法配置,可以根據必定的條件對緩存進行清空

@CacheEvict 主要的參數:

1)value:緩存的名稱,在 spring 配置文件中定義,必須指定至少一個

例如:@CachEvict(value="mycache") 或者 @CachEvict(value={"cache1","cache2"})

2)key:緩存的 key,能夠爲空,若是指定要按照 SpEL 表達式編寫,若是不指定,則缺省按照方法的全部參數進行組合

例如:@CachEvict(value="testcache",key="#userName")

3)condition:緩存的條件,能夠爲空,使用 SpEL 編寫,返回 true 或者 false,只有爲 true 才清空緩存

例如:@CachEvict(value="testcache",condition="#userName.length()>2")

4)allEntries:是否清空全部緩存內容,缺省爲 false,若是指定爲 true,則方法調用後將當即清空全部緩存

例如:@CachEvict(value="testcache",allEntries=true)

5)beforeInvocation:是否在方法執行前就清空,缺省爲 false,

 若是指定爲 true,則在方法尚未執行的時候就清空緩存,

 缺省狀況下,若是方法執行拋出異常,則不會清空緩存

例如:@CachEvict(value="testcache」,beforeInvocation=true)

 

配置+註解的具體使用:

一、pom.xml依賴注入:

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>1.7.6.RELEASE</version>
</dependency>

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>

二、redis.properties(redis緩存配置文件)

master.name=mymaster
master.password=123456
sentinel.host=127.0.0.1
sentinel1.port=26379
sentinel2.port=26380

#緩存數據庫選擇
redis.default.db=3
pool.timeout=100000
pool.maxTotal=100
pool.maxActive=100
pool.maxIdle=10
pool.maxWaitMillis=1000

#是否在borrow一個jedis以前就validate
pool.testOnBorrow=true

#緩存數據的最大生命週期,單位:s,-1永久
redis.expiration=-1

#是否禁用緩存,true禁用
cacheManagers.fallbackToNoOpCache=false

三、在spring.xml(servlet-context.xml)中配置jedis以及cacheManager

<!-- 掃描package方便註解依賴注入-->
    <context:component-scan base-package="com.shop" />

    <!--載入 redis 配置文件-->
    <context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true"/>

    <mvc:annotation-driven/>

    <!-- 開啓緩存註解驅動 -->
    <cache:annotation-driven/><!--缺省了cache-manager="cacheManager"-->

    <!--哨兵配置-->
    <bean id="redisSentinelConfiguration"
          class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
        <property name="master">
            <bean class="org.springframework.data.redis.connection.RedisNode"
            p:name="${master.name}"/><!--要跟哨兵配置文件監控主機名稱一致-->
        </property>
        <property name="sentinels">
            <set>
                <bean class="org.springframework.data.redis.connection.RedisNode"
                    c:host="${sentinel.host}"
                    c:port="${sentinel1.port}"/>
                <bean class="org.springframework.data.redis.connection.RedisNode"
                      c:host="${sentinel.host}"
                      c:port="${sentinel2.port}"/>
            </set>
        </property>
    </bean>

    <!-- jedis pool配置 -->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"
        p:maxTotal="${pool.maxTotal}"
        p:maxIdle="${pool.maxIdle}"
        p:maxWaitMillis="${pool.maxWaitMillis}"
        p:testOnBorrow="${pool.testOnBorrow}"/>

    <!-- spring data redis -->
    <bean id="jedisConnectionFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
          p:pool-config-ref="jedisPoolConfig"
          c:sentinelConfig-ref="redisSentinelConfiguration"
          p:password="${master.password}"
          p:database="${redis.default.db}"/>

    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
          p:connectionFactory-ref="jedisConnectionFactory">

        <!--序列化配置-->
        <property name="keySerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
        </property>
        <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
        </property>
        <property name="hashKeySerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
        </property>
        <property name="hashValueSerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
        </property>
    </bean>

    <!-- 配置cacheManager -->
    <!--使用spring cache--> <!-- simple cache manager -->
    <!--<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
        <property name="caches">
            <set>
                <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default" />
                <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="userCache" />
            </set>
        </property>
    </bean>-->

    <!--redisCacheManager-->
    <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"
          c:redisOperations-ref="redisTemplate"
          p:usePrefix="true" p:transactionAware="true" p:defaultExpiration="${redis.expiration}">
    <!--啓用前綴和事務支持、失效時間-->
    </bean>

    <!-- dummy cacheManager  -->
    <!--在沒有cache容器的狀況下使用緩存機制,系統會拋出異常,
        因此在不想使用緩存機制時,能夠設置fallbackToNoOpCache爲true來禁用緩存-->
    <bean id="cacheManager"
          class="org.springframework.cache.support.CompositeCacheManager"
          p:cacheManagers-ref="redisCacheManager"
          p:fallbackToNoOpCache="${cacheManagers.fallbackToNoOpCache}"/>
        <!--<property name="cacheManagers">
            <list>
                <ref bean="redisCacheManager" />
            </list>
        </property>-->

 

四、使用註解(建議在Service層使用)

public class UserService {

/**
 * @Cacheable:主要針對方法配置,可以根據方法的請求參數對其結果進行緩存
 * #:SpEL表達式
 * 至少指定一個緩存的名稱(value),多個:(value={"cache1","cache2"})
 * 若緩存的key爲空則缺省按照方法的全部參數進行組合,多個key組合:key="#userName.concat(#password)"
 * condition:緩存條件,可爲空  condition="#userName.length()>4"
 */

    @Cacheable(value = "user",key = "#id")
    public User findUserById(Integer id) {
    log.info("findUserFromDB================================================================");
    return userDao.findUserById(id);
    }

    //@CachePut:每次都執行方法體並對返回結果進行緩存操做
    @CachePut(value = "userLoginIdentity",key =     "#user.getId()",condition="#user.getUserName().length()>4")
    public UserLoginIdentity buildUserLoginIdentity(User user){
    UserLoginIdentity userLoginIdentity = new UserLoginIdentity();
    userLoginIdentity.setUserIdString(UserIDBase64.encoderUserID(user.getId()));
    userLoginIdentity.setUserName(user.getUserName());
    userLoginIdentity.setRealName(user.getTrueName());
    return userLoginIdentity;
    }


/**
 * @CacheEvict:清除緩存
 * allEntries:是否清空全部緩存內容,缺省爲 false,若是指定爲 true,則方法調用後將當即清空全部緩存
 * beforeInvocation:是否在方法執行前就清空,缺省爲 false,若是指定爲 true,則在方法尚未執行的時候就清空緩存,
 *                  缺省狀況下,若是方法執行拋出異常,則不會清空緩存
 */
    @CacheEvict(value = {"user","userLoginIdentity"},allEntries = true,beforeInvocation = true)
    public UserLoginIdentity login(String userName, String password) {
    //非空驗證
    AssertUtil.isNotEmpty(userName, "用戶名不能爲空!");
    AssertUtil.isNotEmpty(password, "密碼不能爲空!");

    User user=userDao.findUserByUserName(userName.trim());
    AssertUtil.notNull(user);

    if (!MD5Util.md5Method(password).equals(user.getPassword())) {
    throw new ParamException(103,"用戶密碼錯誤!請從新輸入!");
    }
    return buildUserLoginIdentity(user);
    }
}

 

 

 

關於序列化:keySerializer:這個是對key的默認序列化器。

默認值是StringSerializer。

valueSerializer:這個是對value的默認序列化器,

默認值是取自DefaultSerializer的JdkSerializationRedisSerializer。

hashKeySerializer:對hash結構數據的hashkey序列化器,

默認值是取自DefaultSerializer的JdkSerializationRedisSerializer。

hashValueSerializer:對hash結構數據的hashvalue序列化器,

默認值是取自DefaultSerializer的JdkSerializationRedisSerializer。

 

從執行時間上來看,JdkSerializationRedisSerializer是最高效的(畢竟是JDK原生的),可是序列化的結果字符串是最長的。

JSON因爲其數據格式的緊湊性,序列化的長度是最小的,時間比前者要多一些。

而OxmSerialiabler在時間上看是最長的(當時和使用具體的Marshaller有關)。

因此我的的選擇是傾向使用JacksonJsonRedisSerializer做爲POJO的序列器。 

相關文章
相關標籤/搜索