ssh下:系统初始化实现ServletContextListener接口时,获取spring中数据层对象无效的问题
2015-12-26 23:20
706 查看
想要实现的功能:SSH环境下,数据层都交由Spring管理;在服务启动时,将数据库中的一些数据加载到ServletContext中缓存起来。
系统初始化类需要实现两个接口:
ServletContextListener,系统初始化时调用contextInitialized方法缓存数据;
ApplicationContextAware,获取Spring的ApplicationContext对象,以获取spring容器管理的service对象。
系统初始化类如下:
下面是web.xml里spring和系统初始化的配置:spring是在系统初始化类前加载的
服务启动时,控制台输出如下信息:
首先,从输出的信息来看,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来管理,也没有效果。
如果有其它的办法请分享给我,谢谢!!
系统初始化类需要实现两个接口:
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来管理,也没有效果。
如果有其它的办法请分享给我,谢谢!!
相关文章推荐
- Eclipse 使用自己的签名包进行签名
- Java局部变量final
- java thread源码分析
- 【跟我学spring 4.0 】之第二节-spring Ioc的概述
- Java中的引用传递
- java环境变量的配置
- Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(六)之Initialization & Cleanup
- 【跟我学spring 4.0 】之第一节-springhello 的创建
- spring异常
- java中的内部类
- 使用Spring MVC统一异常处理实战
- Struts2中校验配置问题
- java判断string变量是否是数字的六种方法小结
- Eclipse Helios 配置 Android SDK 2.3 和 ADT 0.9.9
- JavaScrip——练习(求整数和、求整数积)
- java开发中fastjson的使用
- (Java)你的日期还在用String吗?
- 解决Maven项目 Missing artifact jdk.tools:jdk.tools:1.7的错误
- Java突击学习 Day1
- Java中类的加载机制---父类和子类的多态调用