想要实现的功能:SSH环境下,数据层都交由Spring管理;在服务启动时,将数据库中的一些数据加载到ServletContext中缓存起来。

系统初始化类需要实现两个接口:

ServletContextListener,系统初始化时调用contextInitialized方法缓存数据;

ApplicationContextAware,获取Spring的ApplicationContext对象,以获取spring容器管理的service对象。

系统初始化类如下:

 package com.lizhou.action;

 import java.util.List;

 import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component; import com.lizhou.entity.ProductBigType;
import com.lizhou.service.inter.ProductBigTypeServiceInter; /**
* 初始化:实现application缓存数据功能
* 在服务启动时,将数据库中的数据加载进内存
* @author bojiangzhou
*
*/
@Component //这里要该注解,不然无法注入ApplicationContext对象
public class InitAction implements ServletContextListener, ApplicationContextAware { private ApplicationContext ac; @Override
public void contextInitialized(ServletContextEvent event) {
//这里输出当前调用该方法的对象
System.out.println("contextInitialized: "+this); //获取application
ServletContext application = event.getServletContext();
//获取服务层
ProductBigTypeServiceInter bigTypeService = (ProductBigTypeServiceInter) this.ac.getBean("bigTypeService");
//获取商品大类集合
List<ProductBigType> bigTypeList = bigTypeService.findAllBigTypeList();
//保存到application缓存中
application.setAttribute("bigTypeList", bigTypeList);
} @Override
public void setApplicationContext(ApplicationContext ac) throws BeansException {
//这里输出当前调用该方法的对象
System.out.println("setApplicationContext: "+this);
this.ac = ac;
} @Override
public void contextDestroyed(ServletContextEvent event) {
} }

下面是web.xml里spring和系统初始化的配置:spring是在系统初始化类前加载的

 <!-- 添加对spring的支持 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param> <!-- 定义spring的监听器,加载spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- 添加自己的初始化action -->
<listener>
<listener-class>com.lizhou.action.InitAction</listener-class>
</listener>

服务启动时,控制台输出如下信息:

首先,从输出的信息来看,ApplicationContext对象已经注入进来了;

但是,第36行,也就是通过ApplicationContext来获取服务层对象时报错空指针异常了,说明ApplicationContext为空;

造成这个异常的原因很明显:从输出的两个对象来看,调用setApplicationContext方法和contextInitialized方法不是同一个对象,所以在调用contextInitialized方法时,ApplicationContext还是为Null;

因为调用setApplicationContext方法的对象是由Spring初始化的,而调用contextInitialized方法的对象是由tomcat在加载web.xml时通过反射创建的。

所以两个对象不一致。

这里我想到一种解决办法是:将ApplicationContext设置为静态的(static),这样就只有一个ApplicationContext对象了。

private static ApplicationContext ac; //设置为静态

这样就不会报空指针异常了。一切就OK了!

想了想,好像不能将这个初始化类交给Spring来管理,它配置在web.xml中,系统启动时就会触发ServletContextEvent事件,然后调用contextInitialized方法来做初始化工作,它是由tomcat来完成的。即使交由Spring来管理,也没有效果。

如果有其它的办法请分享给我,谢谢!!

ssh下:系统初始化实现ServletContextListener接口时,获取spring中数据层对象无效的问题的更多相关文章

  1. SSH整合中,使用父action重构子类action类.(在父类中获取子类中的泛型对象)

    import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import com.opensymphony.x ...

  2. CentOS下KVM网卡设置成网桥时获取镜像端口的流量

    首先,网桥配置好之后就能实现一个简单的交换机,而交换机的特点就是MAC地址学习,那么KVM的网卡设置成网桥之后,也就是相当于连接到了交换机上. 此时如果要实现在二层交换机或三层交换机做端口镜像,并把这 ...

  3. MyBatis-Spring中间件逻辑分析(怎么把Mapper接口注册到Spring中)

    1.      文档介绍 1.1.      为什么要写这个文档 接触Spring和MyBatis也挺久的了,但是一直还停留在使用的层面上,导致很多时候光知道怎么用,而不知道其具体原理,这样就很难做一 ...

  4. Vue 在beaforeCreate时获取data中的数据

    众所周知,vue在beforecreate时期是获取不到data中的 数据的 但是通过一些方法可以实现在beforecreate时获取到data中的数据 暂时想到两种放发可以实现,vue在before ...

  5. jquery获取html中当前元素对象,以及父对象,相邻的上一个对象,或下一个对象

    jsp代码: <span><input type="hidden" value="1" id="newInfo">& ...

  6. 【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据

    任务描述 本次集中介绍使用Windows和Linux()搭建本地Redis服务器的步骤,从备份的RDB文件中加载数据,以及如何生成AOF文件和通过AOF文件想已经运行的Redis追加数据. 操作步骤 ...

  7. Vue beaforeCreate时获取data中的数据

    异步获取即:通过    $this.$nextTick或者settimeout,这连dom都可以拿出来 beforeCreate() { this.$nextTick(function() { con ...

  8. 链上链下交互 以太坊Dapp接口开发

    主要是指的是用NodeJs调用 提供接口供前端使用 用户查询和转账 以太坊Dapp项目 众筹项目 功能需求 路人 查看所有众筹项目, 2 @ OK 根据众筹项目的address获取该众筹的详情 (参与 ...

  9. Android Wear 数据类型和接口的发送和同步数据概述

    Android Wear数据层API,这是google play service部分,通信信道,以你的手持设备和耐磨应用. Api它包含一系列数据对象,可以让系统通过监控和通知行app重要的事件数据层 ...

随机推荐

  1. Cocos2d-x PluginX (二)增加新的Plugin

    创建Plugin目录 第一步,在plugin/plugins下,目录需要严格按照如下规范实现: plugin/plugins/alipay/proj.android /proj.ios 因为publi ...

  2. java项目常用 BaseDao BaseService

    java项目常用 BaseDao BaseService IBaseDao 1 package com.glht.sim.dao; 2 3  import java.util.List; 4 5 6 ...

  3. submit

    前台<body>中的代码: <body> <div id="top"> </div> <form id="login ...

  4. [caffe]linux下安装caffe(无cuda)以及python接口

    昨天在mac上折腾了一天都没有安装成功,晚上在mac上装了一个ParallelDesktop虚拟机,然后装了linux,十分钟就安装好了,我也是醉了=.= 主要过程稍微记录一下: 1.安装BLAS s ...

  5. Hadoop实战5:MapReduce编程-WordCount统计单词个数-eclipse-java-windows环境

    Hadoop研发在java环境的拓展 一 背景 由于一直使用hadoop streaming形式编写mapreduce程序,所以目前的hadoop程序局限于python语言.下面为了拓展java语言研 ...

  6. vm虚拟机启动失败 Global\vmx86

    workstation12 PRO 启动虚拟机异常报错:无法打开内核设备“\\.\Global\vmx86”: 系统找不到指定的文件 解决方法,启动windows系统服务:

  7. Python之反射

    一.引言 有时候我们会碰到类似这样的需求,就是想要执行类的某个方法,或者需要对对象的某个参数赋值,而方法名或参数名已经包装在类中并不能去顶,需要通过参数传递字符串的形式输入.在这样的情况你会选择什么样 ...

  8. myisam压缩(前缀压缩)索引

    myisam使用前缀压缩来减少索引的大小,从而让更多的索引可以放入内存中,默认只压缩字符串,但通过参数配置也可以对整数做压缩,myisam压缩每个索引块的方法是,先完全保存索引块中的第一个值,然后将其 ...

  9. YTU 2346: 中序遍历二叉树

    原文链接:https://www.dreamwings.cn/ytu2346/2606.html 2346: 中序遍历二叉树 时间限制: 1 Sec  内存限制: 128 MB 提交: 12  解决: ...

  10. 用webdriver+phantomjs实现无浏览器的自动化过程

    环境准备 1. 安装python: 2. 安装pip: 3. 通过pip安装selenium: 4. 下载phantomJS的包并解压缩: 1. 若在Windows系统中,将下载的phantomjs文 ...