关于web项目中无法通过注解获取Spring IOC容器实例空指针异常

初始报错代码如下

package com.spring.servlet;

import com.alibaba.fastjson.JSONObject;
import com.spring.dao.BookDao;
import com.spring.pojo.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: 
 * @className:BookServlet
 * @description:
 * @Date: Create in 18:09 2020/10/9
 * @Version:
 **/
@WebServlet("/book/bookServlet")
public class BookServlet extends BaseServlet{
	@Autowired
    private BookDao bookDao;
    //为什么在web项目中获取不到spring ioc容器中的实例
    //在此处,会进行报错,根据分析,报错原因如下:
    //首先,Tomcat服务器启动时,会通过web.xml进行监听,对spring配置(applicationContext.xml)进行扫描,
    //也就是对容器进行加载,而配置文件中,开启了注解扫描,当扫描到BookServlet时,就遇到了@Autowired,需要从容器中适配bean了
    //而此时,容器都还没有加载成功,尚未对其中的bean进行实例化,所以@Autowired private BookDao bookDao;获得到的值为null
    //因此就会报空指针异常(NullPointerException)
    //解决方法:去掉注解,重写初始化方法

    public void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        System.out.println("========断点=======");
        List<Book> bookList = bookDao.findAll();
        Map<String,Object> map = new HashMap<>();
        map.put("code",0);
        map.put("msg","列表查询");
        map.put("data",bookList);
        //转换JSON格式
        //java对象转换json对象
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(map);
        System.out.println("java对象转换JSON对象:" + jsonObject);
        //将json格式的数据转换成json字符串
        //JSONObject.toJsonString()
        PrintWriter pw = response.getWriter();
        pw.println("Hello");
    }
}

报错如下:

type Exception report

message java.lang.reflect.InvocationTargetException

description The server encountered an internal error that prevented it from fulfilling this request.

exception

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
	com.spring.servlet.BaseServlet.doPost(BaseServlet.java:44)
	com.spring.servlet.BaseServlet.doGet(BaseServlet.java:20)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause

java.lang.reflect.InvocationTargetException
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	java.lang.reflect.Method.invoke(Method.java:498)
	com.spring.servlet.BaseServlet.doPost(BaseServlet.java:41)
	com.spring.servlet.BaseServlet.doGet(BaseServlet.java:20)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause

java.lang.NullPointerException
	com.spring.servlet.BookServlet.list(BookServlet.java:47)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	java.lang.reflect.Method.invoke(Method.java:498)
	com.spring.servlet.BaseServlet.doPost(BaseServlet.java:41)
	com.spring.servlet.BaseServlet.doGet(BaseServlet.java:20)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

根据报错信息提示,在List booklist = bookDao.findAll();处报空指针异常,经断点检查,发现错误源于,bookDao为null。

该错误对于像我这样的spring新手而言,很摸不着头脑,spring配置也没问题,servlet层也没有明显错误。

<!--web.xml-->
<!--初始化spring容器-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:applicationContext.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

错误原因:在Tomcat服务器启动的时候,首先加载web.xml,初始化spring容器,在初始化spring容器时,第一句遇到

<context:component-scan base-package="com.spring"/>

对com.spring包中所有内容进行注解扫描,当扫描到BookServlet时,遇见

@Autowired
private BookDao bookDao;

这里已经开始从容器中取实例了,而此时spring容器尚未初始化完成,因此bookDao得到的就是null。

解决办法:
去掉注解@Autowired,重写init()初始化方法,如下:

private BookDao bookDao;
@Override
public void init() throws ServletException{
    WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
    bookDao = (BookDao) webApplicationContext.getBean("bookDao");
}

成功运行~!
在记录自己学习中遇到的问题的同时,也希望能帮助有需要的伙伴~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值