SSH開發框架中,實現系統啓動加載類,讀取數據庫常用數據進入內存,利用Spring託管,並完成reload功能

各位看官,請做好心理準備,這個帖子會很長,因爲小弟已經做好寫很長的準備。

現在說一下需求,這次的項目是做一個水產養殖相關的項目,系統開啓以後很多地方要用到數據庫裏的字典數據,比如部門表,養殖對象表,這些數據是可變的,但是變化頻率很小,所有每次用到的時候都去數據庫取數據很明顯的是對資源的浪費,所以想按照以前的方法把數據從數據庫裏讀取出來,放到內存,每次用到的時候直接去內存找就可以了。想法應該是正確的,可是用到了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#

發佈了32 篇原創文章 · 獲贊 5 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章