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

SSH开发框架中,实现系统启动加载类,读取数据库常用数据进入内存,利用Spring托管,并完成reload功能

2013-07-11 08:22 1091 查看
各位看官,请做好心理准备,这个帖子会很长,因为小弟已经做好写很长的准备。

现在说一下需求,这次的项目是做一个水产养殖相关的项目,系统开启以后很多地方要用到数据库里的字典数据,比如部门表,养殖对象表,这些数据是可变的,但是变化频率很小,所有每次用到的时候都去数据库取数据很明显的是对资源的浪费,所以想按照以前的方法把数据从数据库里读取出来,放到内存,每次用到的时候直接去内存找就可以了。想法应该是正确的,可是用到了SSH框架,做起来就有点小困难了,研究了一下午,总是是搞定。思路和代码写出来,有错误的地方请大家指正。

正式开始!中间的调错过程省去,直接如何实现。

         另配一个listener,和spring同时启动,不可取。因为listener的启动机制貌似是线程,并不是按顺序一个一个启动,所有想到直接在spring的配置文件里,注册bean文件,让bean文件来执行取数据的工作,但是这个bean显然是不能使用DAO的类,因为DAO层的东西无法注入进来,所以要有个替代的东西,这个东西好难找啊,就是BeanPostProcessor接口,用类PBSTrackManagerPostProcessor实现它其中的一个方法postProcessAfterInitialization,这个方法里可以引入一个类GetDictionaryInfo,实现类的方法getAllInfo(),当getAllInfo去调用DAO层的数据时就可以了。

不说了,直接上源码:

PBSTrackManagerPostProcessor.java

view plaincopy to clipboardprint?

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

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;  

    }  

 



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

view plaincopy to clipboardprint?

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

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;  

    }  

 



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

view plaincopy to clipboardprint?

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

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();  

    }  

 



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

view plaincopy to clipboardprint?

<!-- 调用GetDictionaryInfo 读的 --> 

<bean id="pbsTrackManagerPostProcess" class="edu.ldu.utils.PBSTrackManagerPostProcessor" /> 

<bean id="getDictionaryInfo" class="edu.ldu.utils.GetDictionaryInfo" /> 

 <!-- 调用GetDictionaryInfo 读的 -->

 <bean id="pbsTrackManagerPostProcess" class="edu.ldu.utils.PBSTrackManagerPostProcessor" />

 <bean id="getDictionaryInfo" class="edu.ldu.utils.GetDictionaryInfo" />

 

配置web.xml让MainServlet.java自启动

view plaincopy to clipboardprint?

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

<servlet> 

        <servlet-name>MainServlet</servlet-name> 

        <servlet-class>edu.ldu.utils.MainServlet</servlet-class> 

        <load-on-startup>1</load-on-startup> 

    </servlet> 

<servlet>

  <servlet-name>MainServlet</servlet-name>

  <servlet-class>edu.ldu.utils.MainServlet</servlet-class>

  <load-on-startup>1</load-on-startup>

 </servlet>

然后就是如何在Action里取到数据了:

view plaincopy to clipboardprint?

ServletContext context = ServletActionContext.getServletContext();  

        HashMap dictionaryInfoMap = (HashMap)context.getAttribute("dictionaryInfoMap"); 

ServletContext context = ServletActionContext.getServletContext();

  HashMap dictionaryInfoMap = (HashMap)context.getAttribute("dictionaryInfoMap");

又一个问题就是解决触发一个函数,让这些东西重新加载。

view plaincopy to clipboardprint?

GetDictionaryInfo.getInstance().reloadDictionaryInfoMap(); 

GetDictionaryInfo.getInstance().reloadDictionaryInfoMap();

reloadDictionaryInfoMap();实现起来时比较困难的,要在GetDictionaryInfo 取到ServletContext,而且要必须取到第一次实例的GetDictionaryInfo ,所有有一个东西很好用,就是Spring的context,取到他的方式

view plaincopy to clipboardprint?

private static WebApplicationContext springContext;  

springContext = WebApplicationContextUtils  

        .getWebApplicationContext(_servletContext); 

private static WebApplicationContext springContext;

springContext = WebApplicationContextUtils

  .getWebApplicationContext(_servletContext);

这样就大功告成,跑起来以后的结果,列出控制台的输出数据:

view plaincopy to clipboardprint?

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

%%%%%%%%%%系统启动加载......  

@@@@@@@@@@开始从数据库中取数据!  

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!  

==========~~~~~~~~~~重新加载字典表成功 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/peng_wu01/archive/2010/04/06/5453361.aspx#
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐