首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring Data Redis 整合實戰:兩種方案完整對比

     編輯:Java 相關知識

方案一:使用 Spring Data Redis 官方整合(推薦)

這是最標準、維護性最好的方式,Spring 封裝了底層 Jedis 操作,開發者只需關注業務邏輯。

Maven 依賴配置

<dependencies>
    <!-- 核心依賴 -->
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
        <version>1.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>3.1.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.1.0</version>
    </dependency>
    
    <!-- 日誌相關 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.6.1</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>1.6.1</version>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.1.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>0.9.24</version>
        <scope>runtime</scope>
    </dependency>
</dependencies>

Spring 配置文件

<beans ...>
    <!-- 載入屬性檔 -->
    <context:property-placeholder location="classpath:redis.properties" />
    
    <!-- 掃描 DAO 包 -->
    <context:component-scan base-package="com.x.redis.dao" />
    
    <!-- Jedis 連線池配置 -->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="${redis.maxIdle}" />
        <property name="maxActive" value="${redis.maxActive}" />
        <property name="maxWait" value="${redis.maxWait}" />
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />
    </bean>
    
    <!-- 連線工廠 -->
    <bean id="connectionFactory" 
          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" />
    
    <!-- RedisTemplate:Spring 對 Redis 的核心封裝 -->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
        <property name="connectionFactory" ref="connectionFactory" />
    </bean>
    
    <bean id="userDAO" class="com.x.redis.dao.impl.UserDAOImpl" />
</beans>

屬性檔 redis.properties

redis.host=127.0.0.1
redis.port=6379
redis.pass=
redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true

DAO 實作:使用 RedisTemplate 模板模式

public class UserDAOImpl implements UserDAO {
    @Autowired
    protected RedisTemplate<Serializable, Serializable> redisTemplate;

    public void saveUser(final User user) {
        redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                connection.set(
                    redisTemplate.getStringSerializer().serialize("user.uid." + user.getId()),
                    redisTemplate.getStringSerializer().serialize(user.getName())
                );
                return null;
            }
        });
    }

    @Override
    public User getUser(final long id) {
        return redisTemplate.execute(new RedisCallback<User>() {
            @Override
            public User doInRedis(RedisConnection connection) throws DataAccessException {
                byte[] key = redisTemplate.getStringSerializer().serialize("user.uid." + id);
                if (connection.exists(key)) {
                    byte[] value = connection.get(key);
                    String name = redisTemplate.getStringSerializer().deserialize(value);
                    User user = new User();
                    user.setName(name);
                    user.setId(id);
                    return user;
                }
                return null;
            }
        });
    }
}

測試代碼

public static void main(String[] args) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:/applicationContext.xml");
    UserDAO userDAO = (UserDAO) ac.getBean("userDAO");
    
    User user1 = new User();
    user1.setId(1);
    user1.setName("obama");
    userDAO.saveUser(user1);
    
    User user2 = userDAO.getUser(1);
    System.out.println(user2.getName()); // 輸出: obama
}

方案二:手動整合 Jedis(更靈活,適合深度定製)

不使用 Spring Data Redis 封裝,直接操作 Jedis,並自行建立連線池管理與模板封裝層。

核心差異:使用 ShardedJedisPool 支援分片

<bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool" scope="singleton">
    <constructor-arg index="0" ref="jedisPoolConfig" />
    <constructor-arg index="1">
        <list>
            <bean class="redis.clients.jedis.JedisShardInfo">
                <constructor-arg name="host" value="${redis.host}" />
                <constructor-arg name="port" value="${redis.port}" />
                <constructor-arg name="timeout" value="${redis.timeout}" />
                <constructor-arg name="weight" value="1" />
            </bean>
        </list>
    </constructor-arg>
</bean>

三層封裝架構

  1. RedisDataSource:管理連線獲取與歸還
  2. RedisClientTemplate:封裝具體 Redis 命令(set/get 等)
  3. 業務層:調用 Template 完成業務

關鍵代碼片段

@Repository("redisDataSource")
public class RedisDataSourceImpl implements RedisDataSource {
    @Autowired private ShardedJedisPool shardedJedisPool;
    
    public ShardedJedis getRedisClient() {
        try { return shardedJedisPool.getResource(); }
        catch (Exception e) { log.error("getRedisClent error", e); return null; }
    }
    
    public void returnResource(ShardedJedis shardedJedis) {
        shardedJedisPool.returnResource(shardedJedis);
    }
    
    public void returnResource(ShardedJedis shardedJedis, boolean broken) {
        if (broken) shardedJedisPool.returnBrokenResource(shardedJedis);
        else shardedJedisPool.returnResource(shardedJedis);
    }
}
@Repository("redisClientTemplate")
public class RedisClientTemplate {
    @Autowired private RedisDataSource redisDataSource;
    
    public String set(String key, String value) {
        ShardedJedis jedis = redisDataSource.getRedisClient();
        if (jedis == null) return null;
        
        boolean broken = false;
        try { return jedis.set(key, value); }
        catch (Exception e) { broken = true; throw e; }
        finally { redisDataSource.returnResource(jedis, broken); }
    }
    // get() 等其他方法同理...
}

兩種方案選擇建議

維度Spring Data Redis手動 Jedis 整合
開發效率高(現成模板)中(需自行封裝)
靈活度中高(可控制底層細節)
分片支援需額外配置原生支援 ShardedJedisPool
維護成本低較高

一般專案建議使用方案一;若需複雜分片、特殊連線控制或效能極致優化,可考慮方案二。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved