spring+redis实例(二)
这一篇redis实例是基于序列化储存-(写入对象,读取对象)
在spring+redis(一)中我们介绍了在spring中怎么去操作储存redis,基于string的储存,今天我们介绍一下redis基于序列化的储存。
平常在项目里面往数据库存贮的大多数是一个对象,因为我们好多都是面向对象开发。
下面的例子介绍了往redis数据库里面写入session对象:
1.既然是写入一个对象,我们肯定要有一个对象,下面是一个session class:
package com.lcc.api.dto.session; import java.io.Serializable; import java.util.Map; public class MobileSessionInfo extends SessionInfo implements Serializable { private static final long serialVersionUID = -9170869913976089130L; private Map<String, String> emails; public Map<String, String> getEmails() { return emails; } public void setEmails(Map<String, String> emails) { this.emails = emails; } @Override public String toString() { return new StringBuilder().append("{emails: ").append(emails).append("}").toString(); } }
package com.lcc.api.dto.session; import java.io.Serializable; public abstract class SessionInfo implements Serializable { private static final long serialVersionUID = 6544973626519192604L; private String key; // timestamp private Long createdAt; // unit: second private Long expiryTime; public String getKey() { return key; } public void setKey(String key) { this.key = key; } public Long getCreatedAt() { return createdAt; } public void setCreatedAt(Long createdAt) { this.createdAt = createdAt; } public Long getExpiryTime() { return expiryTime; } public void setExpiryTime(Long expiryTime) { this.expiryTime = expiryTime; } @Override public String toString() { return new StringBuilder().append("{key: ").append(key).append(", createdAt: ").append(createdAt) .append(", expiryTime: ").append(expiryTime).append("}").toString(); } }
2.接下来写一个service去操作写入session对象:
package com.lcc.service.app.impl; import com.lcc.api.dto.session.MobileSessionInfo; import com.lcc.service.BaseAuthorityService; import com.lcc.service.app.DeviceService; import java.util.HashMap; import java.util.Map; public class DeviceServiceImpl implements DeviceService { private BaseAuthorityService authorityService; private Long expiryTime = 24*60*60L; public void setAuthorityService(BaseAuthorityService authorityService) { this.authorityService = authorityService; } public void setExpiryTime(Long expiryTime) { this.expiryTime = expiryTime; } @Override public void catchSession(String deviceId) { MobileSessionInfo session = new MobileSessionInfo(); Map<String, String> emails = new HashMap<String, String>(); session.setKey(deviceId); session.setEmails(emails); session.setExpiryTime(expiryTime); authorityService.saveSessionInfo(session); } }
package com.lcc.service; import com.lcc.domain.enums.SessionCacheMode; import com.lcc.api.dto.session.SessionInfo; public interface BaseAuthorityService { SessionInfo getSessionInfo(String sessionId); void saveSessionInfo(SessionInfo session); SessionCacheMode getCacheMode(); }
package com.lcc.api.domain.enums; public enum SessionCacheMode { LOCAL(1), // REDIS(2); private Integer value; SessionCacheMode(Integer value) { this.value = value; } public Integer getValue() { return value; } public static SessionCacheMode fromValue(Integer value) { for (SessionCacheMode mode : values()) { if (mode.getValue() == value) { return mode; } } return null; } }
package com.lcc.authority; import com.google.common.collect.Maps; import com.lcc.api.domain.enums.SessionCacheMode; import com.lcc.api.dto.session.SessionInfo; import com.lcc.logger.Logger; import com.lcc.logger.LoggerFactory; import com.lcc.service.BaseAuthorityService; import org.joda.time.LocalDateTime; import org.springframework.data.redis.core.RedisTemplate; import java.util.Date; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; public class AuthorityService implements BaseAuthorityService { private static final Logger LOGGER = LoggerFactory.getLogger(AuthorityService.class); private static final String CAHCE_MODE_KEY = "cache-mode"; private RedisTemplate<String, SessionInfo> sessionTemplate; public void setSessionTemplate(RedisTemplate<String, SessionInfo> sessionTemplate) { this.sessionTemplate = sessionTemplate; } /** * session global attributes * <p> * default open redis session cache mode * </p> * */ private static final ConcurrentMap<String, Object> BUCKETS = Maps.newConcurrentMap(); static { BUCKETS.put(CAHCE_MODE_KEY, SessionCacheMode.REDIS); } @Override public SessionInfo getSessionInfo(String sessionId) { LOGGER.info("get session {}, cache mode {}", sessionId, getCacheMode()); SessionInfo sessionInfo = null; try { sessionInfo = sessionTemplate.opsForValue().get(sessionId); } catch (Exception e) { LOGGER.error("get session from redis exception", e); } return sessionInfo; } @Override public void saveSessionInfo(SessionInfo session) { session.setCreatedAt(LocalDateTime.now().toDate().getTime()); try { sessionTemplate.opsForValue().set(session.getKey(), session); sessionTemplate.expire(session.getKey(), session.getExpiryTime(), TimeUnit.SECONDS); } catch (Exception e) { LOGGER.error("H5 save session exception, open local cache mode", e); } } @Override public SessionCacheMode getCacheMode() { return (SessionCacheMode) BUCKETS.get(CAHCE_MODE_KEY); } }
3.基本的java class搞定了,然后看下spring配置文件:
<bean class="org.springframework.data.redis.core.RedisTemplate" id="authorityCacheRedisJdkSerializationTemplate" p:connection-factory-ref="h5SessionRedisConnectionFactory"> <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/> </property> <property name="valueSerializer"> <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/> </property> </bean> <bean id="h5SessionRedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="${redis.session.host}" p:port="${redis.session.port}"> <constructor-arg index="0" ref="jedisPoolConfig" /> </bean> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="60"/> <property name="maxIdle" value="15"/> <property name="testOnBorrow" value="true"/> </bean>
<bean id="deviceService" class="com.opentrans.otms.service.xtt.impl.DeviceServiceImpl"> <property name="authorityService" ref="authorityService" /> <property name="expiryTime" value="${session.expiry.time}" /> </bean> <bean id="authorityService" class="com.opentrans.otms.authority.AuthorityService" > <property name="sessionTemplate" ref="authorityCacheRedisJdkSerializationTemplate" /> </bean>
总结:redis序列化操作和文本操作最主要的区别是RedisTemplate里面两个属性的配置不同:
一个是keySerializer一个是valueSerializer(StringRedisSerializer|JdkSerializationRedisSerializer)
<bean class="org.springframework.data.redis.core.RedisTemplate" id="truckkCacheRedisJdkSerializationTemplate" p:connection-factory-ref="truckCacheRedisConnectionFactory"> <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/> </property> <property name="valueSerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/> </property> </bean> <bean class="org.springframework.data.redis.core.RedisTemplate" id="authorityCacheRedisJdkSerializationTemplate" p:connection-factory-ref="h5SessionRedisConnectionFactory"> <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/> </property> <property name="valueSerializer"> <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/> </property> </bean>