精通Spring Boot——第七篇:整合Redis實現緩存

項目中用到緩存是很常見的事情, 緩存可以提高系統訪問的速度,減輕對數據庫的壓力等好處。今天咱們來說講怎麼在spring boot 中整合redis 實現對數據庫查詢結果的緩存。 首先第一步要作的就是在pom.xml文件添加spring-boot-starter-data-redis。 要整合緩存,必不可少的就是咱們要繼承一個父類CachingConfigurerSupport。咱們先看看這個類的源碼java

public class CachingConfigurerSupport implements CachingConfigurer {
    // Spring's central cache manage SPI ,
	@Override
	@Nullable
	public CacheManager cacheManager() {
		return null;
	}
    //key的生成策略
	@Override
	@Nullable
	public KeyGenerator keyGenerator() {
		return null;
	}
    //Determine the Cache instance(s) to use for an intercepted method invocation.
	@Override
	@Nullable
	public CacheResolver cacheResolver() {
		return null;
	}
    //緩存錯誤處理
	@Override
	@Nullable
	public CacheErrorHandler errorHandler() {
		return null;
	}

}

RedisConfig類git

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(listenerAdapter, new PatternTopic("chat"));
        return container;
    }

    @Bean
    MessageListenerAdapter listenerAdapter(Receiver receiver) {
        return new MessageListenerAdapter(receiver, "receiveMessage");
    }

    @Bean
    Receiver receiver(CountDownLatch latch) {
        return new Receiver(latch);
    }

    @Bean
    CountDownLatch latch() {
        return new CountDownLatch(1);
    }


    public class Receiver {
        private CountDownLatch latch;

        @Autowired
        public Receiver(CountDownLatch latch) {
            this.latch = latch;
        }

        public void receiveMessage(String message) {
            latch.countDown();
        }
    }


    @Bean
    public KeyGenerator myKeyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object o, Method method, Object... objects) {
                StringBuilder sb = new StringBuilder();
                sb.append(o.getClass().getName());
                sb.append(method.getName());
                for (Object obj : objects) {
                    sb.append(JSON.toJSONString(obj));
                }
                return sb.toString();
            }
        };
    }

    /**
     * @param redisConnectionFactory
     * @return
     * @// TODO: 2018/4/27 redis fastjson序列化
     */
    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate")
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        //使用fastjson序列化
        FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
        // 全局開啓AutoType,不建議使用
        // ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        // 建議使用這種方式,小範圍指定白名單
        ParserConfig.getGlobalInstance().addAccept("com.developlee.models.");
        // value值的序列化採用fastJsonRedisSerializer
        template.setValueSerializer(fastJsonRedisSerializer);
        template.setHashValueSerializer(fastJsonRedisSerializer);
        // key的序列化採用StringRedisSerializer
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean
    @ConditionalOnMissingBean(StringRedisTemplate.class)
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    /**
     * @return
     * @// TODO: 2018/4/27 設置redis 緩存時間 5 分鐘
     */
    @Bean
    public RedisCacheConfiguration redisCacheConfiguration() {
        FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
        RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
        configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer)).entryTtl(Duration.ofMinutes(5));
        return configuration;
    }
}

這段代碼中,重點關注對象是RedisTemplate 和StringRedisTemplate還有RedisMessageListenerContainer,RedisTemplate和StringRedisTemplate設置了一些序列化的參數和指定序列化的範圍(主要爲了防止黑客利用Redis的序列化漏洞),@ConditionalOnMissingBean註解的意思就是若是容器中沒有這個類型Bean就選擇當前Bean。RedisMessageListenerContainer是爲Redis消息偵聽器提供異步行爲的容器,主要處理低層次的監聽、轉換和消息發送的細節。github

再來看看application.xml咱們的配置 , so easy~~redis

spring:
   redis:
     database: 0  # Redis數據庫索引(默認爲0)
     host: 192.168.0.100 # Redis服務器地址 (默認爲127.0.0.1)
     port: 6379    # Redis服務器鏈接端口 (默認爲6379)
     password: 123456   # Redis服務器鏈接密碼(默認爲空)
     timeout: 2000  # 鏈接超時時間(毫秒)
  cache:
    type: redis

接下來咱們就能夠使用Redis緩存了,在Service層咱們用註解@Cacheable來緩存查詢的結果。spring

@Cacheable(value= "orderDetailCache", keyGenerator = "myKeyGenerator", unless = "#result eq null")
    public OrderDetailEntity findOrderDetail(OrderDetailEntity orderDetailEntity) {
        return orderDetailDao.findEntity(orderDetailEntity);
    }

到這裏咱們就已經整合了Redis緩存了,是否是很簡單的呢?本身多動手嘗試哦!數據庫

最後,以上示例代碼可在個人github.com中找到。 個人我的公衆號:developlee的瀟灑人生。 關注了也不必定更新,更新就不得了了。json

qrcode_for_gh_2bd3f44efa21_258

相關文章
相關標籤/搜索