SpringBoot配置了redis,启动时会尝试连接吗

问题描述

JDK1.8,springBoot版本1.5.8
我依据网上教程,配置了redis的相关设置,我发现即使我不写redis的IP和端口,redis启动时也不会报错,难道这不和MySQL一样,会尝试连接吗?

自己的尝试

  1. 检查了下,自己的本机没有redis启动,端口6379未被占用
  2. 检查了下,host文件并没有映射到奇奇怪怪的东西
  3. 认真看了下日志,和redis相关的可能出问题也只有这一句
2019-05-08 16:56:57.995  INFO 8028 -- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'redisConfig' of type [com.bowensun.film.common.config.redis.RedisConfig$$EnhancerBySpringCGLIB$$9d643ae7] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

但是似乎没有啥问题

以下是相关代码

application.yml

    database: 0
    password: 285413
    host: 192.168.1.106
    port: 6379
    pool:
      max-active: 8
      max-wait: 3000
      max-idle: 4000
      min-idle: 0
    timeout: 5000
  cache:
    type: redis

启动类

@SpringBootApplication
//@ServletComponentScan
@EnableCaching
public class FilmApplication extends SpringBootServletInitializer {

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

    /**
     *
     *
     * @param builder
     * @return
     */
    @Override
    protected SpringApplicationBuilder configure(
            SpringApplicationBuilder builder) {
        return builder.sources(this.getClass());
    }

}

redis配置类

package com.bowensun.film.common.config.redis;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;


/**
 * redis配置类
 *
 * @author bowensun
 * @date 2018/11/18
 */
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        // 设置序列化工具
        setSerializer(template);
        template.afterPropertiesSet();
        return template;
    }

    private void setSerializer(RedisTemplate template) {
        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);
        template.setKeySerializer(jackson2JsonRedisSerializer);
        template.setValueSerializer(jackson2JsonRedisSerializer);
    }

    // 缓存管理器
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        // 设置缓存过期时间(秒)
        cacheManager.setDefaultExpiration(3600);
        return cacheManager;
    }

    @Bean(value = "customerKeyGenerator")
    @Override
    public KeyGenerator keyGenerator(){
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder key = new StringBuilder();
                key.append(target.getClass().getSimpleName());
                key.append(":").append(method.getName());
                key.append(StringUtils.arrayToDelimitedString(params,"_")) ;
                return key.toString();
            }
        };
    }

    @Bean
    public ValueOperations<String, String> opsForValue(RedisTemplate<String, String> redisTemplate){
        return redisTemplate.opsForValue();
    }

}

pom.xml

        <!--cache-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <!--redisredis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
我总感觉可能犯了很傻的错误,欢迎各位来指正
阅读 10.7k
3 个回答

我理解一楼说的是正确的,我用的是spring-boot-data-redis,例如通过源码例如我们调用redisTemplate.hasKey(),源码内容是这样的:

    @Override
    public Boolean hasKey(K key) {

        byte[] rawKey = rawKey(key);

        return execute(connection -> connection.exists(rawKey), true);
    }

这里面调用了execute方法,从字面理解就是执行的意思,但是内部代码简单分析是在execute里面建立连接的,并不是在初始化的时候建立连接,初始化的时候只是设置启动时需要的配置信息以及调用信息,execute源码如下所示:

@Nullable
    public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) {

        Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it");
        Assert.notNull(action, "Callback object must not be null");

        RedisConnectionFactory factory = getRequiredConnectionFactory();
        RedisConnection conn = null;
        try {

            if (enableTransactionSupport) {
                // only bind resources in case of potential transaction synchronization
                conn = RedisConnectionUtils.bindConnection(factory, enableTransactionSupport);
            } else {
                conn = RedisConnectionUtils.getConnection(factory);
            }

            boolean existingConnection = TransactionSynchronizationManager.hasResource(factory);

            RedisConnection connToUse = preProcessConnection(conn, existingConnection);

            boolean pipelineStatus = connToUse.isPipelined();
            if (pipeline && !pipelineStatus) {
                connToUse.openPipeline();
            }

            RedisConnection connToExpose = (exposeConnection ? connToUse : createRedisConnectionProxy(connToUse));
            T result = action.doInRedis(connToExpose);

            // close pipeline
            if (pipeline && !pipelineStatus) {
                connToUse.closePipeline();
            }

            // TODO: any other connection processing?
            return postProcessResult(result, connToUse, existingConnection);
        } finally {
            RedisConnectionUtils.releaseConnection(conn, factory);
        }
    }

清楚地发现当调用execute的时候内部RedisConnection对象是空的,是在方法内部进行连接操作的,希望能帮到您解除疑惑。

事实上,他只有操作时才会尝试连接,

(⊙﹏⊙)b 你把连接池最小设置为0,没有使用当然不会创建连接。pool.min-idle

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题