首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >spring 在Thread中注入@Resource失败,总为null的解决方案

spring 在Thread中注入@Resource失败,总为null的解决方案

作者头像
似水的流年
发布于 2019-12-06 06:22:18
发布于 2019-12-06 06:22:18
77300
代码可运行
举报
文章被收录于专栏:电光石火电光石火
运行总次数:0
代码可运行

@Resource

private MyMapper myDao;

但是运行的时候,进入到这个线程,这个myDao总为null,也就是注入失败。

运行项目将会发现NullPointerException,也就是说SelectDataService的实例没有被注入到变量selectDataService中。那么,这是什么原因呢?首先来看看配置文件。 

下面是web.xml:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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>
<listener>
    <listener-class>com.test.TestTaskListener</listener-class>
</listener>

在启动web项目时,Servlet容器(比如Tomcat)会读web.xml配置文件中的两个节点和,节点用来加载appliactionContext.xml(即Spring的配置文件),节点用来创建监听器(比如TestTaskListener)实例。Listener的生命周期是由servlet容器管理的,例中的TestTaskListener是由servlet容器实例化并调用其contextInitialized方法的,但是,SelectDataService是通过@Service注解的,也就是说SelectDataService是由Spring容器管理的,在Spring容器外无法直接通过依赖注入得到Spring容器管理的bean实例的引用。为了在Spring容器外得到Spring容器管理的bean,可以使用Spring提供的工具类WebApplicationContextUtils。也就是说,可以在servlet容器管理的Listener中使用该工具类获Spring管理的bean。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class TestTaskListener implements ServletContextListener {
      //Context()初始化方法
      @Override
      public void contextInitialized(ServletContextEvent sce) {
          //获得Spring容器
          WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
          //从Spring容器中获得SelectDataServlet的实例
          SelectDataService selectDataService = ctx.getBean(SelectDataService.class);
          //新建一个定时管理器
          new TestTimerManager();
      }
      public TestTaskListener() {
          super();
      }
      @Override
      public void contextDestroyed(ServletContextEvent sce) {         
      }
  }

那么在Listener中获得的SelectDataService实例如何在TestTimerTask中使用呢?可以通过作为参数传递过去,看如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class TestTaskListener implements ServletContextListener {
      //Context()初始化方法
      @Override
      public void contextInitialized(ServletContextEvent sce) {
          //获得Spring容器
          WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
          //从Spring容器中获得SelectDataServlet的实例
          SelectDataService selectDataService = ctx.getBean(SelectDataService.class);
          //新建一个定时管理器
          new TestTimerManager(selectDataService);
      }
      public TestTaskListener() {
          super();
      }
      @Override
      public void contextDestroyed(ServletContextEvent sce) {         
      }
  }

public class TestTimerManager {
      //新建一个定时器
      Timer timer = new Timer();

      public TestTimerManager(SelectDataService selectDataService) {
          super();
          //新建一个定时任务
          TestTimerTask task = new TestTimerTask(selectDataService);
          //设置定时任务
          timer.schedule(task, firstTimeToStartTheTask, period);
      }   
  }

@Configuration
  public class TestTimerTask extends TimerTask {
      private SelectDataService selectDataService;

      public TestTimerTask(SelectDataService selectDataService) {
          super();
          this.selectDataService = selectDataService;
      }
      @Override
      public void run(){
          try {
              //访问数据库
              MyData myData = selectDataService.selectMyDataById(id);
          }catch(Exception ex) {
              System.out.println("定时任务出错");
              ex.printStackTrace();
          }
      }
  }

再回到web.xml  由于Servlet容器在初始化TestTaskListener时,获取了Spring容器,所以必须保证,在此之前,Spring容器已经初始化完成。因为Spring容器的初始化也是由Listener(ContextLoaderListener)完成,该监听器用Spring框架提供,可以在web应用启动时启动Spring容器。所以,在web.xml中,要先配置ContextLoaderListener,再配置TestTaskListener。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-05-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
ServletContext与Web应用以及Spring容器启动
Servlet容器在启动时会加载Web应用,并为每个Web应用创建唯一的ServletContext对象。
良月柒
2019/03/20
9520
ServletContext与Web应用以及Spring容器启动
Spring 的启动过程
spring的启动过程是IOC容器的启动过程,本质是创建和初始化bean工厂(BeanFactory)。BeanFactory是Spring IOC的核心,Spring使用beanFactory来实例化,配置和管理bean。
长乐坡头
2024/01/19
2720
9-Spring集成web环境
通过new ClassPathXmlApplicationContext(“applicationContext.xml”)来获取应用上下文,不过这种方式获取的弊端就是所有web层的服务使用前都需要利用new ClassPathXmlApplicationContext(“applicationContext.xml”);加载配置文件,导致配置文件需要重复被加载多次,应用上下文的对象也需要创建多次
Ywrby
2022/10/27
3480
怎么获取Spring的ApplicationContext
在 WEB 开发中,可能会非常少须要显示的获得 ApplicationContext 来得到由 Spring 进行管理的某些 Bean, 今天我就遇到了,在这里和大家分享一下, WEB 开发中,怎么获取 ApplicationContext
全栈程序员站长
2022/07/13
9900
WebXml文件与SpringMVC的联系
无论采用何种框架来进行Java Web的开发,只要是Web项目必须在WEB-INF下有web.xml,这是java规范。 当然,我们最早接触到Java Web容器通常是tomcat,但这并不意味着web.xml是属于Tomcat的,同样,Servlet本身也不属于Tomcat,它与JSP等是Java Web的基础规范。而Servlet的运行需要有Servlet容器的支持,常见的容器有Tomcat、Jetty、JBoss等。
w4ngzhen
2023/10/16
3790
WebXml文件与SpringMVC的联系
对于某些不会变又经常需要用的数据的处理
将从数据库查到的信息缓存起来,只访问一次数据库,以后要用直接从内存拿来用:#application.topPrivilegeList
Java架构师必看
2021/05/17
2510
Spring框架:第九章:Spring整合Web
Spring整合Web 在web工程中添加Spring的jar包。 Spring的核心包 spring-beans-4.0.0.RELEASE.jar spring-context-4.0.0.RELEASE.jar spring-core-4.0.0.RELEASE.jar spring-expression-4.0.0.RELEASE.jar aop包 spring-aop-4.0.0.RELEASE.jar spring-aspects-4.0.0.RELEASE.jar com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar JDBC-ORM包 spring-jdbc-4.0.0.RELEASE.jar spring-orm-4.0.0.RELEASE.jar spring-tx-4.0.0.RELEASE.jar Spring的web整合包 spring-web-4.0.0.RELEASE.jar 测试包 spring-test-4.0.0.RELEASE.jar
Java廖志伟
2022/09/28
2970
Spring框架:第九章:Spring整合Web
【小家Spring】Spring环境中(含Boot环境),web组件(Servlet、Filter)内注入使用Spring容器里的Bean
在日常web开发中,我们经常会使用到Filter,这个组件最经典的使用场景就是鉴权。比如现在的JWT鉴权模式,所有的请求都应该携带一个Token,然后我们在Filter里去调用Service方法去校验这个Token是否合法,从而达到鉴权的目的。
YourBatman
2019/09/03
2.6K0
看过spring源码吗_thinkphp源码分析
servlet规范当中,使用了Listener监听器机制来进行web容器相关组件的生命周期管理以及Event事件监听器来实现组件之间的交互。
全栈程序员站长
2022/09/22
5560
看过spring源码吗_thinkphp源码分析
Spring源码-父子容器
Spring源码-父子容器 什么是IOC容器? 最主要是完成了完成对象的创建和依赖的管理注入等等。 Spring的容器主要用途? 在Spring整体框架的核心概念中,容器是核心思想,就是用来管理Be
秋日芒草
2018/05/15
7130
【详解】如何用Spring将Service注入到Servlet中
在Java Web开发中,​​Servlet​​ 是一个非常重要的组件,它用于处理客户端的请求并生成响应。而 ​​Spring​​ 框架则是一个广泛使用的依赖注入框架,可以帮助开发者管理应用中的对象及其依赖关系。本文将介绍如何使用 Spring 框架将 Service 层的对象注入到 Servlet 中,从而实现更灵活、更模块化的代码结构。
大盘鸡拌面
2025/01/02
2230
[Spring框架] Spring中的 ContextLoaderListener 实现原理.
前言: 这是关于Spring的第三篇文章, 打算后续还会写入AOP 和Spring 事务管理相关的文章, 这么好的两个周末 都在看code了, 确实是有所收获, 现在就来记录一下. 在上一篇讲解Spring IOC的文章中, 每次产生ApplicationContext工厂的方式是:  ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); 这样产生appli
一枝花算不算浪漫
2018/05/18
6700
细说Spring Boot初始化DispatcherServlet
在Spring Boot框架未出现之前,要开发一个基于Spring MVC框架的项目,通常需要在Java web项目的描述符文件web.xml中添加如下配置:
编程随笔
2023/10/15
9540
细说Spring Boot初始化DispatcherServlet
Spring学习笔记(4)一SpringMVC启动原理和WebApplicationContext
在分析SpringMVC框架具体组件之前,我们先了解Spring WebApplicationContext。
黄规速
2022/04/14
6150
Spring学习笔记(4)一SpringMVC启动原理和WebApplicationContext
Spring4.04中实现bean的scope(范围)设置为session或者request
Sping中bean的scope的值可以是singleton、prototype、request、session、global session。默认情况下是singleton。
克虏伯
2019/04/15
1.2K0
Spring4.04中实现bean的scope(范围)设置为session或者request
Spring框架:第九章:Spring整合Web
Spring整合Web 在web工程中添加Spring的jar包。 Spring的核心包 spring-beans-4.0.0.RELEASE.jar spring-context-4.0.0.RELEASE.jar spring-core-4.0.0.RELEASE.jar spring-expression-4.0.0.RELEASE.jar aop包 spring-aop-4.0.0.RELEASE.jar spring-aspects-4.0.0.RELEASE.jar com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar JDBC-ORM包 spring-jdbc-4.0.0.RELEASE.jar spring-orm-4.0.0.RELEASE.jar spring-tx-4.0.0.RELEASE.jar Spring的web整合包 spring-web-4.0.0.RELEASE.jar 测试包 spring-test-4.0.0.RELEASE.jar
马克社区
2022/09/21
2090
深入理解Spring系列之七:web应用自动装配Spring配置
在《深入理解Spring系列之一:开篇》的示例代码中使用如下方式去加载Spring的配置文件并初始化容器。 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationgContext.xml"); 在web应用中,配置文件都是自动加载的,示例代码中的方式就不能满足需求了。在web应用中使用Spring,需要在web.xml中添加如下配置。 <listener> <listen
JavaQ
2018/04/04
7590
面试之Spring的启动原理
为什么突然说一下Spring启动原理呢,因为之前面试的时候,回答的那可谓是坑坑洼洼,前前后后,补补贴贴。。。
Java技术债务
2022/08/09
2870
面试之Spring的启动原理
Spring——Web应用中的IoC容器创建(WebApplicationContext根应用上下文的创建过程)
基于Spring-4.3.7.RELEASE Spring的配置不仅仅局限在XML文件,同样也可以使用Java代码来配置。在这里我使用XML配置文件的方式来粗略地讲讲WebApplicationContext。 一提到Spring,首先就应该能想到的是IoC和AOP,什么是IoC、AOP不在这里做讲解。Spring提供一个最为基础的IoC容器——BeanFactory,但这个IoC容器所能提供给我们的功能比较少,所以我们通常选用另一个——ApplicationContext(应用上下文)来作为我们的IoC容
用户1148394
2018/01/09
8540
Spring的一些零碎知识点整理
要想在Web工程中配置Spring,首先需要在工程加入spring-web包,我这里使用的是maven的web工程,pom.xml配置文件配置的依赖如下:
端碗吹水
2020/09/23
2840
Spring的一些零碎知识点整理
推荐阅读
相关推荐
ServletContext与Web应用以及Spring容器启动
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验