《转载》Cannot get Jedis connection; nested exception is java.lang.NullPointerException

spring-data-redis用配置类连接时,抛异常RedisConnectionFailureException: Cannot get Jedis connection; nested exception is java.lang.NullPointerException


作者:小城风带香
来源:CSDN
原文:https://blog.csdn.net/xwq911/article/details/51017960/
前提:redis服务器已经运行,且端口号,服务器地址都已经配置正常,但任然抛出无法获取连接异常
原来的代码如下:

 @Bean
    public JedisConnectionFactory connectionFactory(){
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
        jedisConnectionFactory.setUsePool(true);
        jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
        jedisConnectionFactory.setHostName(environment.getProperty("redis.host"));
        jedisConnectionFactory.setPort(
        				Integer.parseInt(environment.getProperty("redis.port")));
        return jedisConnectionFactory;
    }

其他配置都很正常,但是运行后会抛出空指针异常。

org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is java.lang.NullPointerException
	at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:198)
	at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:345)
	at org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:128)
	at org.springframework.data.redis.core.RedisConnectionUtils.bindConnection(RedisConnectionUtils.java:66)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:176)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:153)
	at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:88)
	at org.springframework.data.redis.core.DefaultValueOperations.set(DefaultValueOperations.java:169)
	at com.qianzhi.testRedis.TestRedisSetinelService.main(TestRedisSetinelService.java:36)
Caused by: java.lang.NullPointerException
	at redis.clients.jedis.BinaryJedis.<init>(BinaryJedis.java:101)
	at redis.clients.jedis.Jedis.<init>(Jedis.java:78)
	at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:193)
	... 8 more

解决方法如下,在return前添加如下代码:

 jedisConnectionFactory.afterPropertiesSet();

看源码便知原因:看jedis如何获取到连接的:

public JedisConnection getConnection() {
		Jedis jedis = fetchJedisConnector();
		JedisConnection connection = (usePool ? 
						new JedisConnection(jedis, pool, dbIndex) 		
						: new JedisConnection(jedis,
				null, dbIndex));
		connection.setConvertPipelineAndTxResults(convertPipelineAndTxResults);
		return postProcessConnection(connection);
	}

我们看fetchJedisConnector()方法:

protected Jedis fetchJedisConnector() {
		try {
			if (usePool && pool != null) {
				return pool.getResource();
			}
			Jedis jedis = new Jedis(getShardInfo());
			// force initialization (see Jedis issue #82)
			jedis.connect();
			return jedis;
		} catch (Exception ex) {
			throw new RedisConnectionFailureException("Cannot get Jedis connection", ex);
		}
	}

如果没用用pool的话,需要用到getShardInfo()方法,而这个方法就是返回一个JedisShardInfo shardInfo。那么这个JedisShardInfo shardInfo在什么时候初始化呢?查看后发现,哈哈在这:

public void afterPropertiesSet() {
		if (shardInfo == null) {
			shardInfo = new JedisShardInfo(hostName, port);
 
			if (StringUtils.hasLength(password)) {
				shardInfo.setPassword(password);
			}
 
			if (timeout > 0) {
				setTimeoutOn(shardInfo, timeout);
			}
		}
 
		if (usePool) {
			this.pool = createPool();
		}
	}

这个方法将在所有的属性被初始化后调用。但是会在init前调用。是spring中InitializingBean接口的方法。spring-data-redis里面实现了它。在这里对shardIndo类进行了初始化。所以,我们只要在代码中添加:

jedisConnectionFactory.afterPropertiesSet();

这句就可以啦。再运行一次,连接成功!


作者:小城风带香
来源:CSDN
原文:https://blog.csdn.net/xwq911/article/details/51017960/
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/weixin_43671497/article/details/89424894
今日推荐