记一次非Spring托管的类注入对象报空指针异常的问题
报错信息
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-05-22 21:14:51.138 ERROR 12844 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'virtualReadListener' defined in file [D:\develop\eshare-library\backend\eshare-library-server\eshare-library-blade-core\target\classes\com\leiter\eshare\bladeCore\intelligentBookshelf\reader\service\impl\VirtualReadListener.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.leiter.eshare.bladeCore.intelligentBookshelf.reader.service.impl.VirtualReadListener]: Constructor threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1302)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1196)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:847)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:140)
at org.springblade.core.launch.BladeApplication.run(BladeApplication.java:49)
at com.leiter.eshare.borrowing.EshareLibraryBorrowingServerApplication.main(EshareLibraryBorrowingServerApplication.java:22)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.leiter.eshare.bladeCore.intelligentBookshelf.reader.service.impl.VirtualReadListener]: Constructor threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:184)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1294)
... 17 common frames omitted
Caused by: java.lang.NullPointerException: null
at org.springblade.core.tool.utils.SpringUtil.getBean(SpringUtil.java:44)
at com.leiter.eshare.bladeCore.intelligentBookshelf.reader.service.impl.VirtualReadListener.<init>(VirtualReadListener.java:30)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:172)
... 19 common frames omitted
Disconnected from the target VM, address: '127.0.0.1:61430', transport: 'socket'
Process finished with exit code 1
开发场景
我在开发时有这样的需求,就是将service类注入到一个实现类中,这个类实现了监听器接口,所以无需Spring托管来实现业务代码。进而就衍生出一个问题,没有Spring托管的类是不能用@Autowire的注入Bean的,那如何注入呢?我在网上搜到了解决方案:
这里是引用网上的方案 :如何在非Spring容器管理的类中注入/获取 Spring容器中的 Bean?
我按照上面的做法写了个util类继承ApplicationContextAware类实现getBean方法在监听实现类中获取bean,但还是报空指针异常,异常定位就是在SpringUtil.getBean()那一行,我还是在网上找办法,最后原因是我这个SpringUtil工具类在类加载的时候没有初始化,我看老人的代码,是把这个获取bean的调用代码用静态块包起来,这样能保证在类加载的时候初始化,但可气的是,我在监听实现类中的方法不能写成静态的,所以这种方法也pass了
@DependsOn(value = {“springUtil”}) 最后是这个注解解决报错了
意思是监听实现类要依赖于SpringUtil类,SpringUtil类会优先注册到ioc容器中
文章中说 @DependsOn 与 @Component 注解搭配使用
那其实有 @Component 注解 就是已经把该监听实现类交给Spring托管啦
也可以通过Spring注入bean的方式注入service类的,找了半天答案还是让Spring托管了,不过总算是解决了,又掌握了个注解,也算是收货颇丰,小小记录一下,如果可以给你带来帮助那就更好啦