14.1. Spring框架整合

Redisson不仅完美地支持运行在Spring框架下,还提供了和Spring框架的各项特性类似的,以Spring XML的命名空间的方式配置RedissonClient实例和它所支持的所有对象和服务。

首先需要做的是向你的Spring XML文件增加一个Redisson的引用描述:

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xmlns:redisson="http://redisson.org/schema/redisson"
  5. xsi:schemaLocation="
  6. http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/context
  9. http://www.springframework.org/schema/context/spring-context.xsd
  10. http://redisson.org/schema/redisson
  11. http://redisson.org/schema/redisson/redisson.xsd
  12. ">
  13. ...
  14. </beans>

然后按照配置方法文档中介绍的方法配置需要的Redisson实例类型。比如一个单Redis节点模式的配置方法如下:

  1. <!-- 最基本配置 -->
  2. <redisson:client>
  3. <!-- 默认地址是 127.0.0.1:6379 -->
  4. <redisson:single-server/>
  5. </redisson:client>
  6. <!-- 或者 -->
  7. <redisson:client>
  8. <redisson:single-server address="${redisAddress}"/>
  9. </redisson:client>

其它连接类型的使用范例以及所有的可变参数均可在配置方法文档中找到。

你可能注意到上面例子里使用了一个属性表达式来指定连接的地址。这种使用方式是直接通过Spring自身提供的功能来实现的,你只需要在你的XML文件中增加一个<context:property-placeholder/>元素标签即可。如果你希望在项目中使用Spring提供的自动依赖注入功能,请不要忘了同时增加<context:annotation-config/>的元素标签。

通常情况下在一个应用程序里创建一个Redisson实例就已经能够满足正常的使用了,但是在个别的情况下,一个应用程序可能会遇到需要同时连接多个不同的Redis环境,这就需要多个Redisson实例同时并存。你可以通过定义多个<redisson:client/>元素标签来实现这个要求:

<redisson:client id="myRedisson1" name="redisson1,redisson2" >
    <redisson:single-server address="127.0.0.1:6379" client-name="1"/>
</redisson:client>

<redisson:client id="myRedisson2" name="redisson3,redisson4">
    <redisson:single-server address="127.0.0.1:6380" client-name="2"/>
</redisson:client>

Redisson实例之间是通过它们的id属性值来区分的,这个值也同时被用来在自动依赖注入时作为qualifier的备选值使用。在name属性中出现的多个由英文逗号分开的值是作为这个bean的化名的方式来解析的,它们在自动依赖注入时也会被用来作为qualifier的备选值使用。

也可以通过定义一个qualifier元素标签来明确的指定它的qualifier备选值,但是这个元素标签不能同时和name属性共存。

<redisson:client>
    <qualifier value="qualifiedName"/>
    <redisson:single-server address="127.0.0.1:6379"/>
</redisson:client>

除了定义Redisson实例以外,其它Redisson提供的对象和服务也可以通过类似的方式来定义。它们既可以作为<Redisson:client/>的子元素在它的内部申明,和可以在XML文件的其他地方申明。在外部申明的时候需要指定一个Redisson bean的引用。

代表Redisson对象的XML元素采用了Spring建议的命名法则。它们和Redisson一样都使用了同样的命名空间:

<redisson:client id="myRedisson">
    <redisson:single-server address="127.0.0.1:6379"/>
    <redisson:map id="map" key="map"/>
</redisson:client>
<!-- 或者 -->
<redisson:map id="map1" key="map" redisson-ref="myRedisson"/>

同样的道理,Redisson提供的服务也可以用同样的方法来获取:

<redisson:client id="myRedisson">
    <redisson:single-server address="127.0.0.1:6379"/>
    <redisson:executor-service
        id="executorService"
        service="executorServiceName"/>
</redisson:client>
<!-- 或者 -->
<redisson:executor-service
    id="executorService"
    service="executorServiceName"
    redisson-ref="myRedisson"/>

不仅如此,对于Redisson的分布式远程服务(Remote Service)分布式实时对象(Live Object)服务来说,你可以通过同样的Spring XML命名空间的方式来实现服务的注册和服务对象的获取:

<redisson:remote-service
    id="remoteService"
    service="remoteServiceName"
    redisson-ref="myRedisson">
    <!-- 注册服务 -->
    <redisson:rpc-server
        api-class="com.example.MyTestService"
        bean="myTestServiceBean"/>
    <!-- 获取代理后的服务对象 -->
    <redisson:rpc-client
        id="client"
        api-class="com.example.MyTestService">
        <redisson:remote-invocation-options>
            <redisson:remote-ack within="1" time-unit="SECONDS"/>
            <redisson:remote-result within="1" time-unit="SECONDS"/>
        </redisson:remote-invocation-options>
    </redisson:rpc-client>
</redisson:remote-service>
<!-- 服务对象 -->
<bean id="myTestServiceBean" class="com.example.MyTestServiceImpl"/>

<redisson:live-object-service
    id="live-object-service-ext"
    redisson-ref="myRedisson">
    <!-- 注册类 -->
    <redisson:live-object-registration  class="com.example.MyTestEntity"/>
    <!-- 获取代理后的实例 -->
    <redisson:live-object
        id="liveObject"
        object-id="testLiveObjectId"
        class="com.example.MyTestEntity"/>
</redisson:live-object-service>

很明显在这些服务被申明在一个<redisson:client/>元素标签的内部时,它的redisson-ref属性可以略去不用写。

下面是所有支持的对象和服务的使用范例:

<redisson:client>
    <redisson:single-server address="127.0.0.1:6379"/>
    <redisson:binary-stream id="binary-stream" key="binary-stream"/>
    <redisson:geo id="geo" key="geo"/>
    <redisson:set-cache id="set-cache" key="set-cache"/>
    <redisson:map-cache id="map-cache" key="map-cache"/>
    <redisson:bucket id="bucket" key="bucket"/>
    <redisson:buckets id="buckets"/>
    <redisson:hyper-log-log id="hyper-log-log" key="hyper-log-log"/>
    <redisson:list id="list" key="list"/>
    <redisson:list-multimap id="list-multimap" key="list-multimap"/>
    <redisson:list-multimap-cache id="list-multimap-cache" key="list-multimap-cache"/>
    <redisson:local-cached-map id="local-cached-map" key="local-cached-map">
        <redisson:local-cached-map-options id="local-options" eviction-policy="LRU" time-to-live="1" time-to-live-unit="SECONDS"/>
    </redisson:local-cached-map>
    <redisson:map id="map" key="map"/>
    <redisson:set-multimap id="set-multimap" key="set-multimap"/>
    <redisson:set-multimap-cache id="set-multimap-cache" key="set-multimap-cache"/>
    <redisson:semaphore id="semaphore" key="semaphore"/>
    <redisson:permit-expirable-semaphore id="permit-expirable-semaphore" key="permit-expirable-semaphore"/>
    <redisson:lock id="lock" key="lock"/>
    <redisson:fair-lock id="fair-lock" key="fair-lock"/>
    <redisson:read-write-lock id="read-write-lock" key="read-write-lock">
        <redisson:read-lock id="read-lock"/>
        <redisson:write-lock id="write-lock"/>
    </redisson:read-write-lock>
    <redisson:multi-lock id="multi-lock">
        <ref bean="lock"/>
        <redisson:lock id="lock-1" key="lock-1"/>
        <redisson:fair-lock id="fair-lock-1" key="fair-lock-1"/>
        <redisson:write-lock id="write-lock-1" read-write-lock-ref="read-write-lock"/>
        <redisson:read-lock id="read-lock-1" read-write-lock-ref="read-write-lock"/>
    </redisson:multi-lock>
    <redisson:red-lock id="red-lock">
        <ref bean="lock"/>
        <redisson:lock id="lock-2" key="lock-2"/>
        <redisson:fair-lock id="fair-lock-2" key="fair-lock-2"/>
        <redisson:write-lock id="write-lock-2" read-write-lock-ref="read-write-lock"/>
        <redisson:read-lock id="read-lock-2" read-write-lock-ref="read-write-lock"/>
    </redisson:red-lock>
    <redisson:set id="set" key="set"/>
    <redisson:sorted-set id="sorted-set" key="sorted-set"/>
    <redisson:scored-sorted-set id="scored-sorted-set" key="scored-sorted-set"/>
    <redisson:lex-sorted-set id="lex-sorted-set" key="lex-sorted-set"/>
    <redisson:topic id="topic" topic="topic"/>
    <redisson:pattern-topic id="pattern-topic" pattern="pattern-topic"/>
    <redisson:blocking-fair-queue id="blocking-fair-queue" key="blocking-fair-queue"/>
    <redisson:queue id="queue" key="queue"/>
    <redisson:delayed-queue id="delayed-queue" destination-queue-ref="queue"/>
    <redisson:priority-queue id="priority-queue" key="priority-queue"/>
    <redisson:priority-deque id="priority-deque" key="priority-deque"/>
    <redisson:blocking-queue id="blocking-queue" key="blocking-queue"/>
    <redisson:bounded-blocking-queue id="bounded-blocking-queue" key="bounded-blocking-queue"/>
    <redisson:deque id="deque" key="deque"/>
    <redisson:blocking-deque id="blocking-deque" key="blocking-deque"/>
    <redisson:atomic-long id="atomic-long" key="atomic-long"/>
    <redisson:atomic-double id="atomic-double" key="atomic-double"/>
    <redisson:count-down-latch id="count-down-latch" key="count-down-latch"/>
    <redisson:bit-set id="bit-set" key="bit-set"/>
    <redisson:bloom-filter id="bloom-filter" key="bloom-filter"/>
    <redisson:script id="script"/>
    <redisson:executor-service id="executor-service" service="executor-service"/>
    <redisson:remote-service id="remote-service" service="remote-service">
        <redisson:rpc-server api-class="com.example.MyTestService" bean="myServiceBean"/>
        <redisson:rpc-client id="rpc-client" api-class="com.example.MyTestService">
            <redisson:remote-invocation-options id="options">
                <!-- 以下二选一 --> 
                <!--<redisson:remote-no-ack/>-->
                <redisson:remote-ack within="1" time-unit="SECONDS"/>
                <!-- 以下二选一 -->                     
                <!--<redisson:remote-no-result/>-->
                <redisson:remote-result within="1" time-unit="SECONDS"/>
            </redisson:remote-invocation-options>
        </redisson:rpc-client>
    </redisson:remote-service>
    <redisson:keys id="keys"/>
    <redisson:live-object-service id="live-object-service">
        <redisson:live-object-registration  class="com.example.MyEntity" />
        <redisson:live-object id="live-object" object-id="live-object" class="com.example.MyEntity" />
    </redisson:live-object-service>
</redisson:client>

Spring的qualifier元素标签可以作为子节点被放置在所有上面提到的类型里。

Redisson提供的底层Redis客户端也可以用同样的方式来获取。

<!-- 底层Redis客户端最基本配置-->
<!-- 默认使用的主机为127.0.0.1,端口为6379 -->
<redisson:redis/>
<!-- 或者 -->
<redisson:redis
    host="127.0.0.1"
    port="6379"
    connection-timeout="10000"
    command-timeout="10000"/>