likes
comments
collection
share

Spring使用注解注入属性为null的问题排查

作者站长头像
站长
· 阅读数 24

最近一直在互联网公司实习,遇到了一个独立开发一个sdk的需求。依赖于以前自己的项目经验,首先创建了一个Maven项目,然后引入Spring的依赖,然后开始一顿劈啦啪啦疯狂输出,等到写完install运行demo测试的时候,疯狂的NPE(NullPointerException)击垮了我最后的心理防线。

Spring使用注解注入属性为null的问题排查 接下来,我就给大家提供一下我出错的思路并复显一下当时的场景。希望大家能够从中得到一些启发。emmmm,其实总结下来就是遇到问题不要慌。

检查你的Spring配置

当你发现业务组件中的某个属性通过@Autowired或者@Resource注入之后值为null时,我想你的第一反应是不可思议(PS:我淦,神🐎鬼?我的代码没有问题,一定有其他原因)。遇到这种情况,不要惊慌,微信面对,客服恐惧最好的办法就是战胜恐惧,奥利给。

Spring使用注解注入属性为null的问题排查 其实发生这种问题大家谁都不想的吗,那既然出现了,我建议你在想着怎么跑路之前先检查一下自己的Spring配置,毕竟如果连配置都有问题,那Spring就是神仙,也没办法正确的帮我们完成Bean装配的工作。

具体需要检查的点有以下几个:

  1. 你的组件上面是否加入了合适的注解。例如:@Controller,@Service, @Repository,@Component等。(PS:什么,又没配置又没加注解,你想怎样?)
  2. 检查一下你context-scan扫描器配置的路径是否正确。即你的包扫描器是否能够扫描到你的注解组件。(如果你是SpringBoot用户就请检查一下你的包是否和主入口程序在一个目录下,并且检查@ComponentScan配置的路径是否正确)

通过以上的检查,我们首先要保证我们的Bean能够交付给Spring容器进行统一的管理。

检查实例化的方式

这一点也是很多初学者常见的错误,我内部属性都注入了,为什么我new了一个对象,里面的属性值全是null?这可一点都不快乐。出现这个问题主要是我们获取对象的方式出了错。我们知道,Spring就是一个bean的容器,由容器负责对象的初始化和依赖注入。当我们想要从中获取一个Bean的实例时,我们应该从Spring容器当中获取。如:new ClassPathXmlApplicationContext("classpth:applicationContext.xml").getBean(String beanName);又或者,我们应该依靠注解,由Spring帮助我们将依赖注入。而如果我们自己new一个类的实例,便绕过了容器的依赖注入过程,因此也可能出现获取不到应有的属性这种情况。(你的东西不是人家工作做的,你又跑去找人家工厂说人家缺仅短两,你可能会被打死的,兄弟。)

检查注入的位置

楼主在写代码时出现的第一个注入为空的场景,就是把@Autowired注解加在了一个静态属性上。当时的抓耳挠腮让我至今记忆犹新,不过冷静下来之后仔细思考,竟能一窥究竟。Spring帮助我们做属性的自动注入,是在帮助我们实例化Bean之后完成的。而static属性标示该属性是归属于类而不是实例的。换句话说,当我们想给static属性注入值的时候,对象还没创建的。因此一定会出现注入为空的情况。

由于Bean初始化顺序导致的问题

这种情况是在业务当中真实可能出现,并且并不好思考的地方。楼主遇到的场景是实现了一个Filter,在Filter当中需要注入业务层组件实现一些过滤逻辑。代码写完之后我发现ServerBean一直为空,我把上面三种方式可能出现问题的地方都做了检查也没有解决。后来Google了一下让我茅塞顿开。原来web容器启动是按照一定顺序的,即:Listener --> Filter -->Servlet。而我们的Service组件依赖与Servlet的Controller组件而创建,因此在创建Filter实例时,由于Servlet实例还没有初始化也会导致依赖无法注入的情况。

综上,当我们的项目当中出现类似问题的时候,并不需要过于紧张。只需要冷静下来,用自己的所学仔细思考就一定可以得到自己想要的反馈。希望能够帮助到各位。