报错
在学习Redis的时候,利用Jedis连接池进行连接Redis服务器进行测试时,报错:Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘redis.clients.jedis.JedisPool’ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
所以,在启动测试类中的testString方法时,报错如下:
- CONDITIONS EVALUATION REPORT
- 最关键的错误在这里 Caused by:
1 项目结构目录
2 RedisConfig
package com.xxx.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
public class RedisConfig {
/**通过Value注解从yml文件中获取redis的配置*/
//redis 服务器IP地址
@Value("${spring.redis.host}")
private String host;
//redis 端口号
@Value("${spring.redis.port}")
private int port;
//redis 服务器密码
@Value("${spring.redis.password}")
private String password;
// 接超时时间
@Value("${spring.redis.timeout}")
private String timeout;
// 最大连接数,默认8
@Value("${spring.redis.jedis.pool.max-active}")
private int maxTotal;
// 最大连接阻塞等待时间,单位毫秒,默认-1ms
@Value("${spring.redis.jedis.pool.max-wait}")
private String maxWaitMillis;
//最大空闲连接,默认8
@Value("${spring.redis.jedis.pool.max-idle}")
private int maxIdle;
//最小空闲连接,默认0
@Value("${spring.redis.jedis.pool.min-idle}")
private int minIdle;
@Bean
public JedisPool getJedisPool() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 最大连接数
jedisPoolConfig.setMaxTotal(maxTotal);
// 最大连接阻塞等待时间
jedisPoolConfig.setMaxWaitMillis(Long.valueOf(maxWaitMillis.substring(0, maxWaitMillis.length()-2)));
// 最大空闲连接
jedisPoolConfig.setMaxIdle(maxIdle);
// 最小空闲连接
jedisPoolConfig.setMinIdle(minIdle);
JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, Integer.valueOf(timeout.substring(0, timeout.length()-2)), password);
return jedisPool;
}
}
3 yml文件
spring:
redis:
# redis 端口号
port: 6379
# redis 服务器IP地址
host: 192.108.2.110
# redis 服务器密码
password: root
# 指定redis数据库,默认为0
database: 0
# 连接超时时间
timeout: 10000ms
jedis:
pool:
# 最大连接数,默认8
max-active: 1024
# 最大连接阻塞等待时间,单位毫秒,默认-1ms
max-wait: 10000ms
# 最大空闲连接,默认8
max-idle: 200
# 最小空闲连接,默认0
min-idle: 5
4 启动类RedisDemoApplication
package com.xxx.redis;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RedisDemoApplication {
public static void main(String[] args) {
SpringApplication.run(RedisDemoApplication.class, args);
}
}
5 测试类的启类
package com.xxx.redis;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import java.util.List;
@SpringBootTest
@RunWith(SpringRunner.class) // 需要加@RunWith注解,否则@Autowired注解获取不到jedisPool连接池对象
public class RedisDemoApplicationTests {
// 注入jedisPool
@Autowired
private JedisPool jedisPool;
//
private Jedis jedis = null;
// 每次运行test前面,先获取jedis对象(初始化jedis对象)
@Before
public void initConn() {
jedis = jedisPool.getResource();
}
/**操作string*/
@Test
public void testString() {
// 添加一条数据
jedis.set("name", "wangwu");
String name = jedis.get("name");
System.out.println(name);
// 添加多条数据,参数的奇数位是key,偶数位是value
jedis.mset("address", "Shanghai", "sex", "1");
List<String> list = jedis.mget("name", "address", "sex");
//System.out.println(list);
list.forEach(System.out::println);// 遍历打印
// 通用的删除命令 del
jedis.del("name");
}
@After
public void closeConn() {
if (null != jedis)
jedis.close();
}
}
原因分析及解决方案
报错的原因是没有找到 bean,具体的原因是:主程序类和其他业务逻辑类不在一个包下,SpringBoot没有扫描到,启动类默认是只会扫描启动类所在包和子包下的注解,所以如果注入的类在上层包就会报错。解决的方法应该是在: SpringBoot的主程序入口类加上@ComponentScan注解,其中参数basePackages为扫描的包。由于我的RedisConfig是在 com.xxx.config 包下,启动类在 com.xxx.redis,因此 basePackages 参数的值应该为:com.xxx。
此时,测试类中的Bean注入,报错已经消失了(jedisPool的红色波浪线消失)