项目中原本使用的是手动获取redis链接池的方式进行的与Spring的整合,现在需要修改为注解的形式。初次接触redis,做个记录。
1. 首先添加 jackson的jar包, 需要添加的 jar包共有三个,分别为:jackson-annoations-2.4.4.jar,jackson-core-2.4.4.jar,jackson-databind-2.4.4.jar,此项目中使用的是同一版本的jar。
2. 更新redis的配置文件,添加redis缓存管理器配置RedisCacheManager,添加redis缓存配置RedisCacheConfig,更新RedisTemplate,添加对key和value的序列化支持:
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
">
<!-- 配置RedisTemplate -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<!-- 设置key和value的序列化 -->
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
</bean>
<!-- 配置JedisConnectionFactory -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="${redis.host}"
p:port="${redis.port}"
p:password="${redis.pass}"
p:pool-config-ref="poolConfig"
/>
<!-- 配置JedisPoolConfig实例 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<!-- 配置RedisCacheConfig -->
<bean id="redisCacheConfig" class="com.fh.dao.redis.RedisCacheConfig">
<constructor-arg ref="jedisConnectionFactory" />
<constructor-arg ref="redisTemplate" />
<constructor-arg ref="redisCacheManager" />
</bean>
<!-- 配置RedisCacheManager -->
<bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
<constructor-arg name="redisOperations" ref="redisTemplate" />
<property name="defaultExpiration" value="${redis.expiration}"/>
<!-- 此处可以设置项目中用到的缓存名称,即@Cache* 标签中的value -->
<constructor-arg name="cacheNames">
<set>
<value>caiya_a</value>
<value>caiya_test</value>
<value>sampleCache1</value>
<value>memoryCache</value>
<value>scanCache</value>
<value>padIndexCache</value>
<value>sampleCache1</value>
<value>sampleCache1</value>
</set>
</constructor-arg>
<!--默认缓存名字-->
<property name="defaultCacheName" value="caiya_a"/>
<!--是否在容器启动时初始化-->
<property name="loadRemoteCachesOnStartup" value="true"/>
<!--是否使用前缀-->
<property name="usePrefix" value="true"/>
<!--前缀命名,仅当usePrefix为true时才生效-->
<property name="cachePrefix">
<bean class="org.springframework.data.redis.cache.DefaultRedisCachePrefix">
<constructor-arg name="delimiter" value=":"/>
</bean>
</property>
<!--缓存名字和有效期的分隔符-->
<property name="separator" value="#"/>
<!--默认有效期1h-->
<!-- 多个缓存有效期,一般的单个工程可以省略此项 -->
<!-- <property name="expires">
<map>
<entry key="caiya_a" value="1800"/>
</map>
</property> -->
</bean>
</beans>
3. 创建RedisCacheConfig缓存配置类:
package com.at.dao.redis;
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.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
/**
* 以Spring与配置文件来管理的redis缓存配置类
*
* 必须添加EnableCaching注解,才能正常启用缓存功能
*
* @author at
* 2018-3-15
*/
@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport {
private volatile JedisConnectionFactory mJedisConnectionFactory;
private volatile RedisTemplate<String, String> mRedisTemplate;
private volatile RedisCacheManager mRedisCacheManager;
public RedisCacheConfig() {
super();
}
public RedisCacheConfig(JedisConnectionFactory mJedisConnectionFactory,
RedisTemplate<String, String> mRedisTemplate, RedisCacheManager mRedisCacheManager) {
super();
this.mJedisConnectionFactory = mJedisConnectionFactory;
this.mRedisTemplate = mRedisTemplate;
this.mRedisCacheManager = mRedisCacheManager;
}
public JedisConnectionFactory redisConnectionFactory() {
return mJedisConnectionFactory;
}
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) {
return mRedisTemplate;
}
public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
return mRedisCacheManager;
}
@Bean
public KeyGenerator customKeyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... objects) {
StringBuilder sb = new StringBuilder();
sb.append(o.getClass().getName());
sb.append(method.getName());
for (Object obj : objects) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
}
4. 更新实体类使其实现序列化,其中:@JsonNaming是jackson 2.1+版本的注解,作用于类或方法,注意这个注解是在jackson-databind包中而不是在jackson-annotations包里,它可以让你定制属性命名策略。@JsonSerialize 用来实现实体类的序列化。
5. 添加对应的dao接口,因此项目使用的是SqlSessionTemplate操作的dao层,此处不再展示代码。
6. 添加 service和serviceimpl。在接口方法的实现上和dao层都可以添加@Cache*注解,此项目中主要添加在service的方法实现上。
// 此注解是将该方法的返回值放入value的缓存下的key的值中,首次请求该方法时会处理缓存。再次请求该方法时,将先查找缓存中是否有对应的key,如果有则跳过方法执行。
@Cacheable(value="value",key="‘key‘")
public List<PageData> getModel(PageData pd) throws Exception {
System.out.println("调用了方法");
return (List<PageData>) dao.getModel(pd);
}
// 此注解跟上面的注解功能相同,但不同的是,该注解将不会使方法跳过执行,而是每次执行后都将新的返回结果更新到value下的key中
@CachePut(value="value", key="‘key‘")
public String updateEndTime(String arg1) {
return arg1;
}
// 此注解将会使缓存中的key清除.
@CacheEvict(value="figure", key="‘figureList‘",beforeInvocation=true)
public int updateFigure(PageData pd) throws Exception{
System.out.println("调用了方法");
return (int) dao.update("CarouseFigureMapper.updateFigure", pd);
}
注意:这些注解中都有的相同的参数为:value,key, condition。value表示使用哪个缓存,是必须指定的参数。key属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当我们没有指定该属性时,Spring将使用默认策略生成key。condition属性可以设置是否使用缓存:condition属性默认为空,表示将缓存所有的调用情形。其值是通过SpringEL表达式来指定的,当为true时表示进行缓存处理;当为false时表示不进行缓存处理,即每次调用该方法时该方法都会执行一次。在@CacheEvict注解中,有两个新的参数,allEntries和beforeInvocation。其中allEntries是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。beforeInvocation可以设置缓存清除的触发时机,清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。
7. 注意事项:注解需要使用在public方法上。带有@Cache* 注解的方法不能被定义在调用该方法的类里,例如controller调用方法A,方法A使用注解,则A不能定义在该controller中。
8. 此处不再记录详细的接口实现等。关于redis更多的学习及使用方法,将在以后持续记录。