深入淺出Redis-Spring整合Redis,redis-springredis

來源:互聯網
上載者:User

深入淺出Redis-Spring整合Redis,redis-springredis
概述:

   在之前的部落格中,有提到過Redis 在服務端的一些相關知識,今天主要講一下Java 整合Redis的相關內容。

   下面是Jedis 的相關依賴:

    

        <dependency>            <groupId>redis.clients</groupId>            <artifactId>jedis</artifactId>            <version>2.5.1</version>        </dependency>        <!-- redis -->        <dependency>            <groupId>org.springframework.data</groupId>            <artifactId>spring-data-redis</artifactId>            <version>1.0.2.RELEASE</version>        </dependency>

 

1、Jedis 單機用戶端

   首先我們瞭解一下,使用Jedis 串連我們的Redis 伺服器:

public static void main(String[] args) {        String host = "127.0.0.1";        int port = 6379;        Jedis jedis = new Jedis(host,port,50000);        jedis.set("name","jayce");        String name = jedis.get("name");        System.out.println(name);        jedis.close();}

  我們先來看直觀的運行結果:

 

 1.1 Jedis 建構函式: 

  我們先從Jedis 的建構函式開始說起,在Jedis的源碼中,我們可以看到Jedis 提供以下幾種建構函式:

  從中我們可以看到一個很重要的資訊,Jedis 繼承BinaryJedis,並且它的所有建構函式都採用了父類的建構函式: 

//根據host 預設連接埠6379擷取串連public Jedis(final String host) {    super(host);    }//根據host 與特定連接埠擷取串連    public Jedis(final String host, final int port) {    super(host, port);    }//根據host 與特定連接埠擷取串連,並且設定key的生命週期    public Jedis(final String host, final int port, final int timeout) {    super(host, port, timeout);    }//根據JedisShardInfo 配置資訊,擷取串連    public Jedis(JedisShardInfo shardInfo) {    super(shardInfo);    }//根據特定URI 擷取串連    public Jedis(URI uri) {    super(uri);   }

   我們可以觀察到父類BinaryJedis 的建構函式中,最終的目的是為了建立一個client,而這個client實質上是一個connection:

  

   

  因此,我們在建立一個Jedis 對象的過程中,建立了一個對伺服器進行串連的Client,而接下來的相關操作,也是由這個client 進行操作。

 

 1.2 Jedis 的Get和Set:

    在調用Get和Set方法之前,我們需要建立一個串連,然後進行相應的操作,下述代碼提供了設定字串,和設定對象到Redis 中,需要注意的是,我們在將對象放到Redis 之前,需要將對象進行序列化,因此對象需要實現Serializable介面

public static void main(String[] args) {        String host = "127.0.0.1";        int port = 6381;        Jedis jedis = new Jedis(host, port);        setString(jedis);        setObject(jedis);        jedis.close();    }    private static void setString(Jedis jedis) {        jedis.set("name", "jayce");        String name = jedis.get("name");        System.out.println(name);    }    private static void setObject(Jedis jedis) {        User user = new User();        user.setId(1);        user.setName("jayce");        user.setPassword("kong");        byte[] values = SerializeUtil.serialize(user);        byte[] names = "user".getBytes();        jedis.set(names, values);        byte[] bytes = jedis.get("user".getBytes());        User userCache = (User) SerializeUtil.unserialize(bytes);        System.out.println(userCache);    }

 

    我們在伺服器中的Redis 中可以看到:

    資料已經緩衝到了Redis 中。

    

    然後,我們再跟蹤一下,Jedis 是如何將一個對象存到了伺服器中的:

    第一步:Jedis 調用 set 方法,然後調用內部的client進行操作:

public String set(final String key, String value) {    checkIsInMulti();    client.set(key, value);    return client.getStatusCodeReply();    }

 

   第二步:client 調用 SafeEncoder.encode(key) 方法,將字串轉換成位元組,再調用client 中的 set(byte[],byte[])方法:

public void set(final String key, final String value) {    set(SafeEncoder.encode(key), SafeEncoder.encode(value));    }public void set(final byte[] key, final byte[] value) {    sendCommand(Command.SET, key, value);   }

 

   第三步:在調用父類Connection中的 sendCommand() 方法,最終將內容傳到伺服器中:

protected Connection sendCommand(final Command cmd, final byte[]... args) {    try {        connect();        Protocol.sendCommand(outputStream, cmd, args);        pipelinedCommands++;        return this;    } catch (JedisConnectionException ex) {        // Any other exceptions related to connection?        broken = true;        throw ex;    }    }

 

 

2、Jedis 單機版整合Spring

    在Spring官網中,給出了這樣得一個Demo:

<?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"  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">  <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="server" p:port="6379" /></beans>

 

    這個設定檔比較直接的幫我們配置了 jedisConectionFactory ,我們需要做的是注入這個Bean 之後,在工廠裡面擷取到Connection,然後進行相應的操作。

 

    根據常用的情境,我們用到的比較多的是 Pool<Jedis>,因此,這裡為大家分享的是JedisPool 的相關配置:

<bean id="redisClient" class="redis.clients.jedis.JedisPool">        <constructor-arg name="host" value="${redis.host}"/>        <constructor-arg name="port" value="${redis.port}"/>        <!--<constructor-arg name="poolConfig" ref="jedisPoolConfig"/>-->    </bean>

 

    

      接下來我們研究一下,JedisPool 的源碼,方便我們對設定檔的理解:

public JedisPool(GenericObjectPoolConfig poolConfig, String host) {        this(poolConfig, host, 6379, 2000, (String)null, 0, (String)null);    }    public JedisPool(String host, int port) {        this(new GenericObjectPoolConfig(), host, port, 2000, (String)null, 0, (String)null);    }    public JedisPool(String host) {        URI uri = URI.create(host);        if(uri.getScheme() != null && uri.getScheme().equals("redis")) {            String h = uri.getHost();            int port = uri.getPort();            String password = uri.getUserInfo().split(":", 2)[1];            int database = Integer.parseInt(uri.getPath().split("/", 2)[1]);            this.internalPool = new GenericObjectPool(new JedisFactory(h, port, 2000, password, database, (String)null), new GenericObjectPoolConfig());        } else {            this.internalPool = new GenericObjectPool(new JedisFactory(host, 6379, 2000, (String)null, 0, (String)null), new GenericObjectPoolConfig());        }    }    public JedisPool(URI uri) {        String h = uri.getHost();        int port = uri.getPort();        String password = uri.getUserInfo().split(":", 2)[1];        int database = Integer.parseInt(uri.getPath().split("/", 2)[1]);        this.internalPool = new GenericObjectPool(new JedisFactory(h, port, 2000, password, database, (String)null), new GenericObjectPoolConfig());    }    public JedisPool(GenericObjectPoolConfig poolConfig, String host, int port, int timeout, String password) {        this(poolConfig, host, port, timeout, password, 0, (String)null);    }    public JedisPool(GenericObjectPoolConfig poolConfig, String host, int port) {        this(poolConfig, host, port, 2000, (String)null, 0, (String)null);    }    public JedisPool(GenericObjectPoolConfig poolConfig, String host, int port, int timeout) {        this(poolConfig, host, port, timeout, (String)null, 0, (String)null);    }    public JedisPool(GenericObjectPoolConfig poolConfig, String host, int port, int timeout, String password, int database) {        this(poolConfig, host, port, timeout, password, database, (String)null);    }    public JedisPool(GenericObjectPoolConfig poolConfig, String host, int port, int timeout, String password, int database, String clientName) {        super(poolConfig, new JedisFactory(host, port, timeout, password, database, clientName));    }

 

    

    JedisPool 的建構函式與上述的Jedis 的建構函式很相似,這裡比較特別的是 GenericObjectPoolConfig 這個配置類,這個類 是org.apache.commons.pool2 包下面的一個用來設定池的大小的類

    我們在配置application.xml檔案的時候,可以自己配置對應的池大小,但是如果沒有相應的設定檔的同學,推薦還是使用預設配置。

 

public static void main(String[] args) {        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-Redis.xml");        Pool<Jedis> jedisPool = (Pool)applicationContext.getBean("redisClient");        Jedis jedis = jedisPool.getResource();        setString(jedis);        setObject(jedis);        jedisPool.returnResource(jedis);    }    private static void setString(Jedis jedis) {        jedis.set("name", "jayce");        String name = jedis.get("name");        System.out.println(name);    }    private static void setObject(Jedis jedis) {        User user = new User();        user.setId(1);        user.setName("jayce");        user.setPassword("kong");        byte[] values = SerializeUtil.serialize(user);        byte[] names = "user".getBytes();        jedis.set(names, values);        byte[] bytes = jedis.get("user".getBytes());        User userCache = (User) SerializeUtil.unserialize(bytes);        System.out.println(userCache);    }

    運行結果:

jayceUser{id=1, name='jayce', password='kong'}

 

 

 

3、總結

    項目源碼:https://github.com/jaycekon/Crawl-Page

    後面會繼續總結,Spring 整合 Redis 叢集~

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.