【原创】SSH开发框架中,实现系统启动加载类,读取数据库常用数据进入内存,利用Spring托管,并完成reload功能
2010-04-06 08:56
1251 查看
各位看官,请做好心理准备,这个帖子会很长,因为小弟已经做好写很长的准备。
现在说一下需求,这次的项目是做一个水产养殖相关的项目,系统开启以后很多地方要用到数据库里的字典数据,比如部门表,养殖对象表,这些数据是可变的,但是变化频率很小,所有每次用到的时候都去数据库取数据很明显的是对资源的浪费,所以想按照以前的方法把数据从数据库里读取出来,放到内存,每次用到的时候直接去内存找就可以了。想法应该是正确的,可是用到了SSH框架,做起来就有点小困难了,研究了一下午,总是是搞定。思路和代码写出来,有错误的地方请大家指正。
正式开始!中间的调错过程省去,直接如何实现。
另配一个listener,和spring同时启动,不可取。因为listener的启动机制貌似是线程,并不是按顺序一个一个启动,所有想到直接在spring的配置文件里,注册bean文件,让bean文件来执行取数据的工作,但是这个bean显然是不能使用DAO的类,因为DAO层的东西无法注入进来,所以要有个替代的东西,这个东西好难找啊,就是BeanPostProcessor接口,用类PBSTrackManagerPostProcessor实现它其中的一个方法postProcessAfterInitialization,这个方法里可以引入一个类GetDictionaryInfo,实现类的方法getAllInfo(),当getAllInfo去调用DAO层的数据时就可以了。
不说了,直接上源码:
PBSTrackManagerPostProcessor.java
GetDictionaryInfo.java
然后这个GetDictionaryInfo.java是个普通的类,所有要有一个servlet启动并且把取得HaspMap放到context里去
MainServlet.java
然后完成注册功能
applicationContext.XML
配置web.xml让MainServlet.java自启动
然后就是如何在Action里取到数据了:
又一个问题就是解决触发一个函数,让这些东西重新加载。
reloadDictionaryInfoMap();实现起来时比较困难的,要在GetDictionaryInfo 取到ServletContext,而且要必须取到第一次实例的GetDictionaryInfo ,所有有一个东西很好用,就是Spring的context,取到他的方式
这样就大功告成,跑起来以后的结果,列出控制台的输出数据:
终于写完,请大家指正。
现在说一下需求,这次的项目是做一个水产养殖相关的项目,系统开启以后很多地方要用到数据库里的字典数据,比如部门表,养殖对象表,这些数据是可变的,但是变化频率很小,所有每次用到的时候都去数据库取数据很明显的是对资源的浪费,所以想按照以前的方法把数据从数据库里读取出来,放到内存,每次用到的时候直接去内存找就可以了。想法应该是正确的,可是用到了SSH框架,做起来就有点小困难了,研究了一下午,总是是搞定。思路和代码写出来,有错误的地方请大家指正。
正式开始!中间的调错过程省去,直接如何实现。
另配一个listener,和spring同时启动,不可取。因为listener的启动机制貌似是线程,并不是按顺序一个一个启动,所有想到直接在spring的配置文件里,注册bean文件,让bean文件来执行取数据的工作,但是这个bean显然是不能使用DAO的类,因为DAO层的东西无法注入进来,所以要有个替代的东西,这个东西好难找啊,就是BeanPostProcessor接口,用类PBSTrackManagerPostProcessor实现它其中的一个方法postProcessAfterInitialization,这个方法里可以引入一个类GetDictionaryInfo,实现类的方法getAllInfo(),当getAllInfo去调用DAO层的数据时就可以了。
不说了,直接上源码:
PBSTrackManagerPostProcessor.java
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * @author ROC * @2010年4月5日18:24:58 * 实现BeanPostProcessor接口,可以实现在Spring加载时,调取一个的对象的方法,使其能够取得实例化以后的DAO. * * * * */ public class PBSTrackManagerPostProcessor implements BeanPostProcessor { public Object postProcessAfterInitialization(Object obj, String s) throws BeansException { if(obj instanceof GetDictionaryInfo)//GetDictionaryInfo为类名 { ((GetDictionaryInfo) obj).getAllInfo();//getAllInfo为GetDictionaryInfo的方法 } return obj; } public Object postProcessBeforeInitialization(Object obj, String s) throws BeansException { return obj; } }
GetDictionaryInfo.java
import java.util.HashMap; import javax.annotation.Resource; import javax.servlet.ServletContext; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import java.util.ArrayList; import edu.ldu.system.preferences.feeding.DAO.TdFeedingRatesDAO; import edu.ldu.system.preferences.product.DAO.TdProductFishDAO; /** * @author ROC * 2010年4月5日18:26:55 * 实现getAllInfo方法,取得所有常用字典表里的数据 * * */ public class GetDictionaryInfo { @Resource private TdFeedingRatesDAO tdFeedingRatesDAO ; @Resource private TdProductFishDAO tdProductFishDAO; public GetDictionaryInfo(){ super(); } private static WebApplicationContext springContext; public static ServletContext _servletContext;//这个是为了取servletContext private static GetDictionaryInfo _instance; public static GetDictionaryInfo getInstance() { springContext = WebApplicationContextUtils .getWebApplicationContext(_servletContext); if(null == _instance) _instance = (GetDictionaryInfo)springContext.getBean("getDictionaryInfo"); return _instance; } public static HashMap<String,ArrayList> dictionaryInfoMap = new HashMap<String, ArrayList>(); public void getAllInfo() { System.out.println("%%%%%%%%%%系统启动加载......"); System.out.println("@@@@@@@@@@开始从数据库中取数据!"); ArrayList tdFeedingRatesList = (ArrayList)tdFeedingRatesDAO.findAll(); System.out.println("数据LIST - 1 的大小 "+tdFeedingRatesList.size()); ArrayList tdProductFishList = (ArrayList)tdProductFishDAO.findAll(); System.out.println("数据LIST - 2 的大小 "+tdProductFishList.size()); System.out.println("@@@@@@@@@@数据从数据库中全部取出!"); dictionaryInfoMap.put("tdFeedingRatesList", tdFeedingRatesList); dictionaryInfoMap.put("tdProductFishList", tdProductFishList); System.out.println("@@@@@@@@@@数据打包完毕,全部放进了dictionaryInfoMap!"); } /** * 重新加载字典表数据! * */ public void reloadDictionaryInfoMap() { System.out.println("==========~~~~~~~~~~系统开始重新加载字典表"); dictionaryInfoMap.clear(); System.out.println("==========~~~~~~~~~~字典表MAP,清空成功!"); getAllInfo(); System.out.println("==========~~~~~~~~~~重新加载字典表成功"); } public HashMap<String, ArrayList> getDictionaryInfoMap() { return dictionaryInfoMap; } public void setDictionaryInfoMap(HashMap<String, ArrayList> dictionaryInfoMap) { this.dictionaryInfoMap = dictionaryInfoMap; } }
然后这个GetDictionaryInfo.java是个普通的类,所有要有一个servlet启动并且把取得HaspMap放到context里去
MainServlet.java
import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.ArrayList; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; public class MainServlet extends HttpServlet { /** * Initialization of the servlet. <br> * * @throws ServletException * if an error occurs */ private static final long serialVersionUID = 1L; // private SystemParamServicesImpl sysParamService; private static WebApplicationContext springContext; private ServletContext context; public void init() throws ServletException { // Put your code here springContext = WebApplicationContextUtils .getWebApplicationContext(this.getServletContext()); GetDictionaryInfo._servletContext=this.getServletContext(); context = this.getServletContext(); // GetDictionaryInfo getDictionaryInfo = new GetDictionaryInfo(); HashMap<String, ArrayList> dictionaryInfoMap = (HashMap<String, ArrayList>) GetDictionaryInfo.dictionaryInfoMap; System.out.println("字典MAP里的数据长度为" + dictionaryInfoMap.size() + "个"); context.setAttribute("dictionaryInfoMap", dictionaryInfoMap); System.out.println("@@@@@@@@@@系统字典表数据加载成功!"); } /** * Constructor of the object. */ public MainServlet() { super(); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request * the request send by the client to the server * @param response * the response send by the server to the client * @throws ServletException * if an error occurred * @throws IOException * if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out .println("<!DOCTYPE HTML PUBLIC /"-//W3C//DTD HTML 4.01 Transitional//EN/">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); out.println(" <BODY>"); out.print(" This is "); out.print(this.getClass()); out.println(", using the GET method"); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to * post. * * @param request * the request send by the client to the server * @param response * the response send by the server to the client * @throws ServletException * if an error occurred * @throws IOException * if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out .println("<!DOCTYPE HTML PUBLIC /"-//W3C//DTD HTML 4.01 Transitional//EN/">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); out.println(" <BODY>"); out.print(" This is "); out.print(this.getClass()); out.println(", using the POST method"); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } }
然后完成注册功能
applicationContext.XML
<!-- 调用GetDictionaryInfo 读的 --> <bean id="pbsTrackManagerPostProcess" class="edu.ldu.utils.PBSTrackManagerPostProcessor" /> <bean id="getDictionaryInfo" class="edu.ldu.utils.GetDictionaryInfo" />
配置web.xml让MainServlet.java自启动
<servlet> <servlet-name>MainServlet</servlet-name> <servlet-class>edu.ldu.utils.MainServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>
然后就是如何在Action里取到数据了:
ServletContext context = ServletActionContext.getServletContext(); HashMap dictionaryInfoMap = (HashMap)context.getAttribute("dictionaryInfoMap");
又一个问题就是解决触发一个函数,让这些东西重新加载。
GetDictionaryInfo.getInstance().reloadDictionaryInfoMap();
reloadDictionaryInfoMap();实现起来时比较困难的,要在GetDictionaryInfo 取到ServletContext,而且要必须取到第一次实例的GetDictionaryInfo ,所有有一个东西很好用,就是Spring的context,取到他的方式
private static WebApplicationContext springContext; springContext = WebApplicationContextUtils .getWebApplicationContext(_servletContext);
这样就大功告成,跑起来以后的结果,列出控制台的输出数据:
%%%%%%%%%%系统启动加载...... @@@@@@@@@@开始从数据库中取数据! Hibernate: select tdfeedingr0_.pk_id as pk1_0_, tdfeedingr0_.fishTypeId as fishTypeId0_, tdfeedingr0_.waterTemperature as waterTem3_0_, tdfeedingr0_.growthStageId as growthSt4_0_, tdfeedingr0_.baitId as baitId0_, tdfeedingr0_.feedingRate as feedingR6_0_, tdfeedingr0_.state as state0_ from LDU_Aquaculture.dbo.td_feeding_rates tdfeedingr0_ 数据LIST - 1 的大小 12 Hibernate: select tdproductf0_.pk_fishid as pk1_7_, tdproductf0_.fishname as fishname7_, tdproductf0_.fish_store as fish3_7_, tdproductf0_.state as state7_, tdproductf0_.creationDate as creation5_7_, tdproductf0_.lastModifiedDate as lastModi6_7_ from LDU_Aquaculture.dbo.td_product_fish tdproductf0_ 数据LIST - 2 的大小 2 @@@@@@@@@@数据从数据库中全部取出! @@@@@@@@@@数据打包完毕,全部放进了dictionaryInfoMap! 字典MAP里的数据长度为2个 @@@@@@@@@@系统字典表数据加载成功! 系统启动,开始装载日志文件…… DEBUG日志文件路径为:E:/Program Files/Tomcat 6.0/webapps/Aquaculture/WEB-INF/logs/app-debug.log INFO日志文件路径为:E:/Program Files/Tomcat 6.0/webapps/Aquaculture/WEB-INF/logs/app-info.log WARN日志文件路径为:E:/Program Files/Tomcat 6.0/webapps/Aquaculture/WEB-INF/logs/app-warn.log ERROR日志文件路径为:E:/Program Files/Tomcat 6.0/webapps/Aquaculture/WEB-INF/logs/app-error.log 2010-4-6 9:35:38 org.apache.coyote.http11.Http11Protocol start 信息: Starting Coyote HTTP/1.1 on http-8080 2010-4-6 9:35:38 org.apache.jk.common.ChannelSocket init 信息: JK: ajp13 listening on /0.0.0.0:8009 2010-4-6 9:35:38 org.apache.jk.server.JkMain start 信息: Jk running ID=0 time=0/31 config=null 2010-4-6 9:35:38 org.apache.catalina.startup.Catalina start 信息: Server startup in 10921 ms ==========~~~~~~~~~~系统开始重新加载字典表 ==========~~~~~~~~~~字典表MAP,清空成功! %%%%%%%%%%系统启动加载...... @@@@@@@@@@开始从数据库中取数据! Hibernate: select tdfeedingr0_.pk_id as pk1_0_, tdfeedingr0_.fishTypeId as fishTypeId0_, tdfeedingr0_.waterTemperature as waterTem3_0_, tdfeedingr0_.growthStageId as growthSt4_0_, tdfeedingr0_.baitId as baitId0_, tdfeedingr0_.feedingRate as feedingR6_0_, tdfeedingr0_.state as state0_ from LDU_Aquaculture.dbo.td_feeding_rates tdfeedingr0_ 数据LIST - 1 的大小 12 Hibernate: select tdproductf0_.pk_fishid as pk1_7_, tdproductf0_.fishname as fishname7_, tdproductf0_.fish_store as fish3_7_, tdproductf0_.state as state7_, tdproductf0_.creationDate as creation5_7_, tdproductf0_.lastModifiedDate as lastModi6_7_ from LDU_Aquaculture.dbo.td_product_fish tdproductf0_ 数据LIST - 2 的大小 2 @@@@@@@@@@数据从数据库中全部取出! @@@@@@@@@@数据打包完毕,全部放进了dictionaryInfoMap! ==========~~~~~~~~~~重新加载字典表成功
终于写完,请大家指正。
相关文章推荐
- SSH开发框架中,实现系统启动加载类,读取数据库常用数据进入内存,利用Spring托管,并完成reload功能
- SSH开发框架中,实现系统启动加载类,读取数据库常用数据进入内存,利用Spring托管,并完成reload功能
- SSH开发框架中,实现系统启动加载类,读取数据库常用数据进入内存以及将数据放在application
- SSH框架---实现系统启动加载类,读取数据库常用数据进入内存以及将数据放在application
- spring-boot框架开发的系统读取到的数据库数据相差8小时的问题解决
- 用Maven整合SpringMVC+Spring+Hibernate 框架,实现简单的插入数据库数据功能
- 用Maven整合SpringMVC+Spring+Hibernate 框架,实现简单的插入数据库数据功能
- 用Maven整合SpringMVC+Spring+Hibernate 框架,实现简单的插入数据库数据功能(二)
- 本文是笔者根据数据库编程经验,利用C++语言的模板、继承、授权、多态等面向对象特性,借鉴命令模式,实现了对象在关系数据中的存储,降低应用系统与数据库之间的耦合,提高开发效率。
- 用Maven整合SpringMVC+Spring+Hibernate 框架,实现简单的插入数据库数据功能(二)
- AutoCompleteExtender实现自动完成功能(从数据库中读取数据 )
- 用Maven整合SpringMVC+Spring+Hibernate 框架,实现简单的插入数据库数据功能
- 在Winform开发框架中,利用DevExpress控件实现数据的快速录入和选择
- 利用实现数据同步功能, 已经完成测试,可以实现.
- 我不要紧的编码组两人,至少两年的dotnet网咯服务开发经验,熟悉数据库orm, 系统管理人员:熟悉各linux发行版的系统管理和安全管理,linux常用数据库的配置与运维等,有代码托管服务管理经验优
- SSH集成框架下真正实现Spring AOP拦截功能
- 基于Spring+SpringMVC+Hibernate框架系统, 利用SpringAOP实现写日志,切入点的Controller层出现@AutoWire 注入Service为null的情况分析
- Android开发之多线程中实现利用自定义控件绘制小球并完成小球自动下落功能实例
- [原创]一个利用PHP语言读取数据库数据的例子(菜鸟版)
- SSH集成框架下真正实现Spring AOP拦截功能