NoSQL专题

使用Spring Data + Redis实现缓存

  首先,我们给一个服务配置Cache,如下:

@Service('helloService')
public class HelloServiceImpl implements HelloService {

    /**
     * Using SpEL for conditional caching - only cache method executions when
     * the name is equal to 'Joshua'
     */
    @Cacheable(value='messageCache', condition=''Joshua'.equals(#name)')
    public String getMessage(String name) {
        System.out.println('Executing HelloServiceImpl' +
                        '.getHelloMessage(\'' + name + '\')');

        return 'Hello ' + name + '!';
    }

}

使用 Jedis 作为Redis的Java客户端,在Spring只要配置三个:

JedisConnectionFactory 有以下参数:

  • hostName=”localhost”
  • port=6379
  • timeout=2000 ms
  • database=0
  • usePool=true
 

RedisTemplate是提供你使用连接池连接,使用JdkSerializationRedisSerializer序列化。

RedisCacheManager 是依赖RedisTemplate提供一个cache接口。

<?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:context='http://www.springframework.org/schema/context'
    xmlns:c='http://www.springframework.org/schema/c'
    xmlns:p='http://www.springframework.org/schema/p'
    xmlns:cache='http://www.springframework.org/schema/cache'
    xsi:schemaLocation='

http://www.springframework.org/schema/beansvhttp://www.springframework.org/schema/beans/spring-beans.xsd

        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd'>

    <context:component-scan base-package='com.joshuawhite.example.service' />
    <context:property-placeholder location='classpath:/redis.properties'/>

    <!-- turn on declarative caching -->
    <cache:annotation-driven />

    <!-- Jedis ConnectionFactory -->
    <bean
        id='jedisConnectionFactory'
        class='org.springframework.data.redis.connection.jedis.JedisConnectionFactory'
        p:host-name='${redis.host-name}'
        p:port='${redis.port}'
        p:use-pool='true'/>

    <!-- redis template definition -->
    <bean
        id='redisTemplate'
        class='org.springframework.data.redis.core.RedisTemplate'
        p:connection-factory-ref='jedisConnectionFactory'/>

    <!-- declare Redis Cache Manager -->
    <bean
        id='cacheManager'
        class='org.springframework.data.redis.cache.RedisCacheManager'
        c:template-ref='redisTemplate'/>

</beans>

使用Java配置等同于上面配置,

package com.joshuawhite.example.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

@Configuration
@ComponentScan('com.joshuawhite.example')
@PropertySource('classpath:/redis.properties')
public class AppConfig {

 private @Value('${redis.host-name}') String redisHostName;
 private @Value('${redis.port}') int redisPort;

 @Bean
 public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
     return new PropertySourcesPlaceholderConfigurer();
 }

 @Bean
 JedisConnectionFactory jedisConnectionFactory() {
     JedisConnectionFactory factory = new JedisConnectionFactory();
     factory.setHostName(redisHostName);
     factory.setPort(redisPort);
     factory.setUsePool(true);
     return factory;
 }

 @Bean
 RedisTemplate<Object, Object> redisTemplate() {
     RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<Object, Object>();
     redisTemplate.setConnectionFactory(jedisConnectionFactory());
     return redisTemplate;
 }

 @Bean
 CacheManager cacheManager() {
     return new RedisCacheManager(redisTemplate());
 }

}

下面是客户端调用代码:

public class App {

    public static void main(String[] args) {

        boolean useJavaConfig  = true;
        ApplicationContext ctx = null;

        //Showing examples of both Xml and Java based configuration
        if (useJavaConfig ) {
                ctx = new AnnotationConfigApplicationContext(AppConfig.class);
        }
        else {
                ctx = new GenericXmlApplicationContext('/META-INF/spring/app-context.xml');
        }

        HelloService helloService = ctx.getBean('helloService', HelloService.class);

        //First method execution using key='Josh', not cached
        System.out.println('message: ' + helloService.getMessage('Josh'));

        //Second method execution using key='Josh', still not cached
        System.out.println('message: ' + helloService.getMessage('Josh'));

        //First method execution using key='Joshua', not cached
        System.out.println('message: ' + helloService.getMessage('Joshua'));

        //Second method execution using key='Joshua', cached
        System.out.println('message: ' + helloService.getMessage('Joshua'));

        System.out.println('Done.');
    }

}

运行输出:

Executing HelloServiceImpl.getHelloMessage('Josh')
message: Hello Josh!
Executing HelloServiceImpl.getHelloMessage('Josh')
message: Hello Josh!
Executing HelloServiceImpl.getHelloMessage('Joshua')
message: Hello Joshua!
Executing HelloServiceImpl.getHelloMessage('Joshua')
message: Hello Joshua!
Done.

 

基于Spring+redis实现pub/sub

Redis Cluster快速安装指南

redis安装

NOSQL专题