springboot的依赖注入报null的问题

最近使用springboot开发项目,使用到了依赖注入,频繁的碰到注入的对象报空指针,错误如下

java.lang.NullPointerException: null
    at com.mayihc.audit.controller.MaterialNkDetailController.download(MaterialNkDetailController.java:72)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
    at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
    at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
    at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
    at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
    at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
    at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
    at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387)
    at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

第一次碰见的情况是:在new出来的对象中使用@Autowired来获取注入的对象

 DateCheckUtils dateCheckUtils = new DateCheckUtils();

我要在这个类中使用依赖注入,刚开始写的是注入方式如下

public class DateCheckUtils {
     @Autowired
    private CompanyInfoService companyInfoService;
 @Autowired
private MaterialNkDetailService materialNkDetailService;

.........
}

这是会报空指针异常,后俩修改代码就解决了问题,修改后的代码如下

1、创建一个类实现ApplicationContextAware,用来获取applicationContext 和bean

package com.mayihc.audit.core.utils;

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

@Component
public class SpringUtils implements ApplicationContextAware{

    private static ApplicationContext applicationContext = null; 

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if(SpringUtils.applicationContext == null){
            SpringUtils.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);
    }  

}

2、在new出来的DateCheckUtils类中获取ApplicationContext的实例

public class DateCheckUtils {
  //获取ApplicationContext的实例
    private ApplicationContext applicationContext = SpringUtils.getApplicationContext();
  //通过applicationContext和反射机制来获取对象
    private CompanyInfoService companyInfoService = applicationContext.getBean(CompanyInfoService.class);
    private MaterialNkDetailService materialNkDetailService = applicationContext.getBean(MaterialNkDetailService.class);
    private MaterialNkLogbookService materialNkLogbookService = applicationContext
            .getBean(MaterialNkLogbookService.class);
    private MaterialNkLedgerService materialNkLedgerService = applicationContext.getBean(MaterialNkLedgerService.class);
    private MaterialGjChangeDetailService materialGjChangeDetailService = applicationContext
            .getBean(MaterialGjChangeDetailService.class);
    private MaterialGjLedgerService materialGjLedgerService = applicationContext.getBean(MaterialGjLedgerService.class);
    .....

}

这样就可以获取到要注入的对象

报空指针的原因:当对象声明为bean组件的时候,他是交给spring容器去管理的,容器会帮你进行初始化;但是如果使用new方法来调用对象是=时,会跳过spring容器生成的对象,这是就无法进行初始化,所以在调用的时候就会出现对象为null,并且对象里面以注入方式引用的对象也为null,被声明为bean对象的组件必修使用注入的方式进行调用。

上述的问题也可以通过将  DataCheckUtils dataCheckUtils=new DataCheckUtils();改为:

@Autowired

private DataCheckUtils dataCheckUtils;来实现

第二种碰见null的情况:在同一个类中只有某个方法在被前端调用的时候报null,其余方法都正常。

错误代码如下

 1  @RequestMapping("/download")
 2     private void download(HttpServletResponse response, MaterialNkDetail materialNkDetail) throws Exception {
 3         SysUser u = (SysUser) SecurityUtils.getSubject().getPrincipal();
 4         if(!"1".equals(u.getType())) {
 5             materialNkDetail.setCompanyId(u.getCompanyInfoId());
 6         }
 7         CompanyInfo companyInfo = companyInfoService.selectByPrimaryKey(u.getCompanyInfoId());
 8         if(companyInfo == null) {
 9             companyInfo = new CompanyInfo();
10             companyInfo.setFullName("全部车辆");
11         }
12     .....
13 }    

当运行这个方法时,注入的对象总是报null,经排查后,此方法是用private修饰的,改为public修饰后就OK了。

原因:容器扫描bean生成代理类的时候,public和protected方法可以被正常代理,而private方法不会被正常代理,属性的注入是在代理类中完成的,所以public和protected方法获取的注入属相是完成注入的属性,private方法获取的是为完成注入的属性,所以是null



原文地址:https://www.cnblogs.com/houqx/p/10048671.html

时间: 2024-08-25 05:22:29

springboot的依赖注入报null的问题的相关文章

spring依赖注入报错

在上一篇文章“spring的主要内容之依赖注入”中,我总结了通过XML配置文件注入的两种方式,分别是构造方法注入和set方法注入.在使用set方法注入时,遇到了一个报错,找了好长时间才找到问题.这个错误是在启动服务时报出来的. 现在分别贴出代码和报错信息. package com.zaoren.controller; import java.util.List; import java.util.Set; import org.springframework.web.bind.annotatio

SpringBoot的拦截器中依赖注入报空指针问题

原因:拦截器加载的时间点在springcontext之前,所以在拦截器中注入自然为null : 解决方法:配置拦截器链的类中先注入这个拦截器,示例: @Configuration public class WebConfig extends WebMvcConfigurerAdapter { //注入拦截器类 @Bean public LocaleInterceptor localeInterceptor  () { return new LocaleInterceptor(); } publi

spring springboot websocket 不能注入( @Autowired ) service bean 报 null 错误

spring 或 springboot 的 websocket 里面使用 @Autowired 注入 service 或 bean 时,报空指针异常,service 为 null(并不是不能被注入). 解决方法:将要注入的 service 改成 static,就不会为null了.参考代码: @Controller @ServerEndpoint(value="/chatSocket") public class ChatSocket { // 这里使用静态,让 service 属于类

SpringBoot系列: 理解 Spring 的依赖注入(二)

==============================Spring 容器中 Bean 的名称==============================声明 bean 有两个方式, 一个是 @Bean, 另一个是 @Component 和它的子类 (包括 @Service/@Controller/@Repository/@Configuration), Spring 容器中 bean 名生成规则分两大类, 分别是: 一. @Component 和它的子注解是用来注解 Class 的. 这些

springboot启动流程(九)ioc依赖注入

所有文章 https://www.cnblogs.com/lay2017/p/11478237.html 正文 在前面的几篇文章中,我们多次提到这么一个转化过程: Bean配置 --> BeanDefinition --> Bean对象 Bean的配置可以是xml配置,也可以是java配置.BeanDefinition配置在内存中数据对象,也是Bean的元数据.在springboot启动过程当中,refresh上下文这个步骤将会解析xml配置以及java配置,从而把Bean的配置解析成为Bea

SpringBoot导入jsp依赖始终报错

先粘出我自己的pom代码: 1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apac

@Qualifier高级应用---按类别批量依赖注入【享学Spring】

每篇一句 罗斯:选秀状元可能有水货,但MVP绝对没有 前言 在上篇文章(讲解@LoadBalanced负载均衡)的末尾,我抛出了一个很重要的问题,建议小伙伴自己深入思考一番:本文主要针对此问题,作出一个统一的答复和讲解. 由于本人觉得这块知识点它属于Spring Framework的核心内容之一,非常的重要,因此单拎出来作专文讲述,希望对你有所帮助. 背景案例 说到@Qualifier这个注解大家并不陌生:它用于"精确匹配"Bean,一般用于同一类型的Bean有多个不同实例的case下

spring中依赖注入方式总结

Spring中依赖注入的四种方式 在Spring容器中为一个bean配置依赖注入有三种方式: · 使用属性的setter方法注入  这是最常用的方式: · 使用构造器注入: · 使用Filed注入(用于注解方式). 使用属性的setter方法注入 首先要配置被注入的bean,在该bean对应的类中,应该有要注入的对象属性或者基本数据类型的属性.例如:为UserBiz类注入UserDAO,同时为UserBiz注入基本数据类型String,那么这时,就要为UserDAO对象和String类型设置se

PHP 依赖注入 (转)

说这个话题之前先讲一个比较高端的思想--'依赖倒置原则' "依赖倒置是一种软件设计思想,在传统软件中,上层代码依赖于下层代码,当下层代码有所改动时,上层代码也要相应进行改动,因此维护成本较高.而依赖倒置原则的思想是,上层不应该依赖下层,应依赖接口.意为上层代码定义接口,下层代码实现该接口,从而使得下层依赖于上层接口,降低耦合度,提高系统弹性" 上面的解释有点虚,下面我们以实际代码来解释这个理论 比如有这么条需求,用户注册完成后要发送一封邮件,然后你有如下代码: 先有邮件类'Email.