您的位置:首页 > 编程语言 > Java开发

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

2015-12-26 23:20 706 查看
想要实现的功能: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来管理,也没有效果。

如果有其它的办法请分享给我,谢谢!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: