zoukankan      html  css  js  c++  java
  • 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

    
    
  • 相关阅读:
    论工作动力的来源是什么?答案是来自于实现自己的梦想
    向梦想者致敬
    内置函数,递归函数,模块与包,开发目录规范
    迭代器,生成器
    闭包函数,装饰器,语法糖
    函数对象,名称空间及查找,作用域
    函数调用与参数
    字符编码
    文件处理
    python 11.5数据类型及常用方法
  • 原文地址:https://www.cnblogs.com/houqx/p/10048671.html
Copyright © 2011-2022 走看看