Prerequisite: Redis server is already running, and port number, server address has been configured properly, but still throw cannot get connection exception
The original code is as follows:
@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;
}
Other configurations are normal, but a null pointer exception is thrown after running.
Request processing failed; nested exception is org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is java.lang.NullPointerException
The solution is as follows, add the following code before return
jedisConnectionFactory.afterPropertiesSet ();
See the source code to see why: see how jedis gets the connection:
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);
}
We look at the fetchJedisConnector () method:
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);
}
}
If you do not use the pool, you need to use the getShardInfo () method, and this method is to return a JedisShardInfo shardInfo. So when is this JedisShardInfo shardInfo initialized? After checking it out, Haha is here:
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 ();
}
}
This method will be called after all properties have been initialized. But it will be called before init. Is the method of the InitializingBean interface in spring. It is implemented in spring-data-redis. The shardIndo class is initialized here. So, we just add:
jedisConnectionFactory.afterPropertiesSet ();
This sentence is fine. Run again and the connection is successful.