今天创建了一个springboot项目,想整合一下redis数据库,结果redisTemplate一直未空指针异常,最后总结:出现在的原因有两点
1.对@Autowired和@Resource不熟
2.对spring依赖注入和new没搞明白
废话少说,先贴上错误代码让大家看看截图配合粘贴代码
1.pom.xml中加入对redis的依赖
<dependency>
<groupId>org.springframework.boot
<artifactId>spring-boot-starter-data-redis
</dependency>
2.application.properties中配置redis
spring.application.name=redis
server.port=8080
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=localhost
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
3.编写redis工具类
启动项目就会报错,下面是报错的信息:
Field redisTemplate in redis.utils.RedisUtil required a bean of type 'org.springframework.data.redis.core.RedisTemplate' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
也就是说没有找到RedisTemplate这个对象,后来百度后才知道原来RedisTemplate<Object,Object>这个bean的key-value默认的泛型都是Object类型的,如果在上面的工具类中,想要引入这个对象,有两种方式
1.用@Resource注解
@Resource
private RedisTemplate<String,Object> redisTemplate;
2.用@Autowired注解
@Autowired
private RedisTemplate redisTemplate;
因为RedisTemplate这个bean的key默认是Object类型的,所以在依赖注入的时候,想将key改为String类型的,所以问题就出在了这里。@Autowired这个注解是根据类型来讲bean注入的,RedisTemplate这个bean在Spring容器中是下图这个样子的,RedisTemplate<Object,Object>,而我上面写的是RedisTemplate<String,Object>,根据类型,Spring容器中没有找到,所以就会报错了;而如果用@Resource的话就可以,因为@Resource这个注解是根据名称在Spring容器中寻找bean的,所以没有问题,这个就是@Autowired和@Resource两个注解的区别
下面看调用redis工具类的一层
报空指针异常,然后将代码改为这样就OK了
为什么会出现这样的情况呢?
这就是文章刚开写的第二个问题了,对spring依赖注入和new没搞明白
在写redisUtil工具类的时候,已经将redisTemplate依赖注入了,这个对象是Spring容器提供的,根据Application.properties的redis配置,redisTemplate已经被Spring封装好了,如果在用redisUtil时,去new这个对象的话,就会是一个新的对象,这个新的redisUtil对象中的redisTemplate对象在Spring容器中也是一个新的对象,而且是一个空的对象,所以在调用的时候redisTemplate会报空指针异常