Distributed caching for SpringBoot applications

  redis, springboot

SpringBoot application series articles

Order

This article mainly talks about how to integrate redis in SpringBoot, and how to use redis cache and efficient set operation function.

Prepare redis

Specific viewDocker Builds redis ClusterIn this article, this article has built a redis cluster with one master and three slaves.

New project

图片描述

Integrated redis

spring.redis.database=0
spring.redis.host=192.168.99.100
#spring.redis.password= # Login password of the redis server.
spring.redis.pool.max-active=8
spring.redis.pool.max-idle=8
spring.redis.pool.max-wait=-1
spring.redis.pool.min-idle=0
spring.redis.port=6379
#spring.redis.sentinel.master= # Name of Redis server.
#spring.redis.sentinel.nodes= # Comma-separated list of host:port pairs.
spring.redis.timeout=10

Simple operation

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = RedisdemoApplication.class)
public class RedisdemoApplicationTests {

    @Autowired
    private StringRedisTemplate template;

    @Autowired
    private DemoService demoService;

    @Test
    public void set(){
        String key = "test-add";
        String value = "hello";
        template.opsForValue().set(key,value);
        assertEquals(value,template.opsForValue().get(key));
    }

    @Test
    public void incr(){
        String key = "test-incr";
        template.opsForValue().increment(key, 1);
        assertEquals(template.opsForValue().get(key),"1");
    }

    @Test
    public void should_not_cached(){
        demoService.getMessage("hello");
    }

    @Test
    public void should_cached(){
        demoService.getMessage("cat");
    }

    @Test
    public void should_cache_bean(){
        ReportBean b1 = demoService.getReport(1L, "2016-01-30", "hello", "world");
        ReportBean b2 = demoService.getReport(1L, "2016-01-30", "hello", "world");
    }

}

Use cache

Specify serialization

@SpringBootApplication
@EnableCaching
public class RedisdemoApplication {

    /**
     * 设置缓存对象的序列化方式,不设置会报错
     * 另外对于json序列化,对象要提供默认空构造器
     * @param redisTemplate
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);

        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        cacheManager.setDefaultExpiration(300);
        return cacheManager;
    }

    /**
     * 自定义key的生成策略
     * @return
     */
    @Bean
    public KeyGenerator myKeyGenerator(){
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    public static void main(String[] args) {
        SpringApplication.run(RedisdemoApplication.class, args);
    }
}

Use instance

@Component
public class DemoService {

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

        return "Hello " + name + "!";
    }

    @Cacheable(value = "reportcache",keyGenerator = "myKeyGenerator")
    public ReportBean getReport(Long id, String date, String content, String title) {
        System.out.println("无缓存的时候调用这里---数据库查询");
        return new ReportBean(id, date, content, title);
    }
}

References