Spring项目报错Exception in thread main java.lang.NullPointerException Cannot invoke com.study.spring.ioc.bean.zhuangpei.zhujie.service.UserService.save() because this.userService is null
1.先来展示一下我的报错
Exception in thread “main” java.lang.NullPointerException: Cannot invoke “com.study.spring.ioc.bean.zhuangpei.zhujie.service.UserService.save()” because “this.userService” is null
2.说下问题
我把我的代码检查了一下午,代码逻辑肯定是没有问题的,那哪里出现了问题呢?
在这里,主要感谢一下高老师,帮我解决问题,并给我提供了一个非常好的思路
👍👍👍👍👍👍👍👍👍👍👍👍
3.原因分析
因为JDK版本升级的改动,在Jdk9~17环境下,搭建Springboot项目,会出现原有@Resource(javax.annotation.Resource)不存在的问题,导致项目从Jdk8迁移到高版本时遇到的问题
你可能会问,为什么javax.annotation.Resource注解不存在呢?
从Jdk9开始,JavaEE从Jdk中分离,jdk就移除掉了javax.annotation.jar包的默认集成,从而导致版本不兼容。所以一旦spring项目从JDK8升到高版本,都会出现javax.annotation.Resource无法引用报红。
java EE 即 java Enterprise Edition,企业级应用,目标是制定一系列企业级应用的标准服务。常见的 javax.servlet, javax.annotation。
Oracle 收购了创造 java 的 SUN 公司,Oracle 又不想发展 java EE 了,就把 java EE 交给 Eclipse 社区了,但是又因为不知名的原因,禁止社区使用 javax 这个名字。所以,javax.servlet 就变成了 jakarta.servlet, jakarta.annotation。api无法向前兼容。
java ee 的最后一个版本也是 8,以后就再也没有 java ee 的新版本。
4.解决方案
(1)Jdk9以上、Springboot3/Spring6.0以前版本的问题
解决方案:
1、手动导入javax.annotation包
<!--引入@Resource注解的包-->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
2、降到Jdk8,你发任你发,我用Java8
(2)Springboot3/Spring6.0以上版本的问题
从Java EE APIs 到 Jakarta EE
Spring Boot 3开始,所有的Java EE Api都需要迁移到Jakarta EE上来。
大部分用户需要修改import相关API的时候,要用jakarta替换javax。比如:原来引入javax.servlet.Filter的地方,需要替换为jakarta.servlet.Filter
但是当Spring版本升级到6.0以上的版本,即使手动引入javax.annotation包,但是还是会有问题,你会发现类无法注入,导致引用的类is Null,报空指针。
因为Spring也放弃了javax.annotation.Resource注解的支持,而是对jakarta.annotation.Resource注解的支持
通过跟代码进去,发现@Resouce的源代码是 jakarta.annotation下的
package jakarta.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Resources.class)
public @interface Resource {
String name() default "";
String lookup() default "";
Class<?> type() default Object.class;
Resource.AuthenticationType authenticationType() default Resource.AuthenticationType.CONTAINER;
boolean shareable() default true;
String mappedName() default "";
String description() default "";
public static enum AuthenticationType {
CONTAINER,
APPLICATION;
private AuthenticationType() {
}
}
}
所以,解决方法是引用jakarta包来解决问题,导入到maven的配置文件中pom.xml
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
</dependency>
(我解决时,用的2.1.1版本的包,10.1.7版本的包不知道为什么导入不成功,不过无伤大雅)
导入成功后
应通过import引入
import jakarta.annotation.Resource;
这样就运行成功了
解决思路来源:敬爱的高老师
博客参考:http://t.csdnimg.cn/tj3rO