继承ApplicationContextAware接口后报空指针NullPointerException异常

前言

曾经在简书上看过一篇博客说写博客时加个前言纯粹是在说废话,其实我觉得我现在确实在说废话,但是前言有一个作用可以让博主描绘此刻的心情,比如我现在解决了这个问题后内心千万只草泥马在奔腾,所以需要写个前言平复一下心情好缕清自己的思路
在这里插入图片描述

工具类

首先我写了一个工具类继承ApplicationContextAware接口方便个别无法使用@Autowired注入的类注入spring容器中
工具类代码如下:

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * @author ZP
 * @date 2020/4/22.
 */
@Component
public class SpringUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    // 获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    // 通过name获取 Bean.
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    // 通过class获取Bean.
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    // 通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (SpringUtil.applicationContext == null) {
            SpringUtil.applicationContext = applicationContext;
        }
    }
}

其实在我写的demo里还是可以正常注入的,但是集成进系统后报错,最怕碰到这种迷惑bug,这边可以,那边不可以。最后通过两边的同时debug猜出问题所在。
比如我的报错在第27行

Caused by: java.lang.NullPointerException: null
	at com.zp.websocket.SpringUtil.getBean(SpringUtil.java:27) ~[classes/:na]
	at com.zp.websocket.MyWebSocket.<init>(MyWebSocket.java:22) ~[classes/:na]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_111]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_111]
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_111]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_111]
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:172) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
	... 19 common frames omitted

这个是在demo成功注入情况下的debug截图
在这里插入图片描述
这是系统失败注入情况下的debug截图
在这里插入图片描述
显而易见,失败的原因是类内部的applicationContext没有被实例,所以我们到实例applicationContext的代码上并加上断点康康
这是成功的时候
在这里插入图片描述
而失败的情况是哪怕打了断点但还没执行重写的setApplicationContext方法就抛出异常了,而我这个工具类只在MyWebSocket.java里用到,他们的位置如图
在这里插入图片描述

是在同一个包下的,demo里的位置是
在这里插入图片描述
在两个不同的包下,那么会不会是因为位置问题,spring启动时的加载类顺序问题,在同一个包下从上而下扫描,所以是先MyWebSocket再SpringUtil。为此我还特地做个试验,把SpringUtil改名为MySpringUtil使其在上面
在这里插入图片描述
结果真的能执行到setApplicationContext并且没有抛异常
在这里插入图片描述
好吧,真的是顺序问题,spring原本先注入我的MyWebSocket,因为我的MyWebSocket里用到了继承ApplicationContextAware的SpringUtil,而此时我的SpringUtil还没注入spring容器里最后导致空指针异常。解决方法就是改一下顺序,让SpringUtil先执行,这样继承ApplicationContextAware的setApplicationContext方法就会先执行确保applicationContext有实例对象,这样就能避免异常了。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值