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>
原文地址:https://www.cnblogs.com/cc-java/p/6625998.html