1. 程式人生 > >使用Spring application物件儲存全域性變數,統計連結的點選量

使用Spring application物件儲存全域性變數,統計連結的點選量

 application物件作為JSP的9大內建物件之一,實現了使用者間資料的共享,可存放全域性變數。它開始於伺服器的啟動,直到伺服器的關閉在此期間,此物件將一直存在;這樣在使用者的前後連線或不同使用者之間的連線中,可以對此物件的同一屬性進行操作;在任何地方對此物件屬性的操作,都將影響到其他使用者對此的訪問。伺服器的啟動和關閉決定了application物件的生命。它是ServletContext類的例項

       基於上述理由,將點選量作為全域性變數,存在application物件中,統計全網的點選量。

1、在web.xml中自定義監聽器

<listener>
     <listener-class>xxx.xxx.web.listener.InitListener</listener-class>
</listener>

2、在xxx.xxx.web.listener.InitListener的contextInitialized()方法中設定全域性變數,用來存點選量,存入ServletContext域物件(application)中,在contextDestroyed()方法中更新資料庫中的點選量欄位,並移除全域性變數。

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* @ClassName: MyServletContextListener
* @Description:InitListener類實現了ServletContextListener介面,


*                 因此可以對ServletContext物件的建立和銷燬這兩個動作進行監聽。
*/ 
public class InitListener implements ServletContextListener {
    private  static ApplicationContext applicationContext = null;

    public void contextInitialized(ServletContextEvent sce) {
        //System.out.println("ServletContext物件建立");

//初始化 ApplicationContext  物件

applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext());

//設定點選量

sce.getServletContext().setAttribute("increaseCountMap",newConcurrentHashMap<Integer,AtomicInteger>());
    }

public void contextDestroyed(ServletContextEvent sce) {
        //System.out.println("ServletContext物件銷燬");

        WebApplicationContext  webApplicationContext= ContextLoader.getCurrentWebApplicationContext();

        //獲取業務層service Bean

CourseServiceImpl courserService = (CourseServiceImpl)webApplicationContext.getBean("CourseServiceImpl");

courserService.updateRateUtilization();//更新點選量

sce.getServletContext().removeAttribute("increaseCountMap");//移除全域性變數--點選量
    }

    //用於那些非控制層中使用直接獲取到的Spring Bean的獲取,如介面

    public static ApplicationContext  getApplicatonContext(){

returnapplicationContext ;

     }
}

3、在CourseController.java控制器中: private static Object obj = new Object(); static ConcurrentHashMap<Integer,AtomicInteger> increaseCountMap= new ConcurrentHashMap<Integer,AtomicInteger>(); @RequestMapping(value="/showCourseDetail.do",method=RequestMethod.GET) public ModelAndView showCourseDetail(HttpServletRequest request){ //其他內容忽略,至關注點選量的業務處理 String courseId = null; synchronized(obj){//加鎖防止併發 courseId = request.getParameter("courseId"); calClickRate(request,courseId ); } //............ return new ModelAndView("/page/courseDetail.jsp"); }
private void  calClickRate(HttpServletRequest request,String courseIdStr){ Integer courseId = Integer.valueOf(courseIdStr); increaseCountMap = (ConcurrentHashMap<Integer,AtomicInteger>)request.getSession().getServletContext(). getAttribute("increaseCountMap"); Iterator it =increaseCountMap.entrySet().iterator(); while(it.hasNext()){ Map.Entry<Integer,AtomicInteger> me = (Map.Entry<Integer,AtomicInteger>)it.next(); if(me.getKey().intValue() == courseId.intValue()){ increaseCountMap.putIfAbsent(courseId,new AtomicInteger(me.getValue().getAndIncrement())); }else{ increaseCountMap.putIfAbsent(courseId,new AtomicInteger(1)); } } if(!it.hasNext()){ increaseCountMap.putIfAbsent(courseId,newAtomicInteger(1)); } request.getSession().getServletContext().setAttribute("increaseCountMap",increaseCountMap); 4、在CourseServiceImpl.java中 更新點選量 public void updateRateUtilization(){ WebApplicationContext  webApplicationContext = ContextLoader.getCurrentWebApplicationContext(); ConcurrentHashMap<Integer,AtomicInteger>countMap =(ConcurrentHashMap<Integer,AtomicInteger>) webApplicationContext .getServletContext().getAttribute("increaseCountMap"); Iterator it =countMap.entrySet().iterator(); while(it.hasNext()){ Map.Entry<Integer,AtomicInteger> me = (Map.Entry<Integer,AtomicInteger>)it.next(); courseMapper.updateCourseClickRate(me.getKey(),me.getValue().intValue());//更新資料庫 } webApplicationContext.getServletContext().setAttribute("increaseCountMap", new ConcurrentHashMap<Integer,AtomicInteger>()); } //====================== updateCourseClickRate()對應的sql:
update t_course set click_rate = #{clickRate} + IFNULL(click_rate,0) where id = #{courseId} 5、最後使用定時任務,每10分鐘一次,更新點選量 CourseServiceImpl.java-->updateRateUtilization()

相關推薦

使用Spring application物件儲存全域性變數統計連結的點

 application物件作為JSP的9大內建物件之一,實現了使用者間資料的共享,可存放全域性變數。它開始於伺服器的啟動,直到伺服器的關閉,在此期間,此物件將一直存在;這樣在使用者的前後連線或不同使用者之間的連線中,可以對此物件的同一屬性進行操作;在任何地方對此物件屬性的

Android中Application儲存全域性變數

在Android應用中使用全域性變數,除了public的靜態變數,還有更優雅的方式是使用android.app.Application。 啟動Application時,系統會建立一個PID,即程序ID,所有的Activity就會在此程序上執行。 那麼我們在A

Spring MVC配置Freemarker全域性變數實現應用全路徑

Xml程式碼   <context:property-placeholder location="classpath:config.properties" ignore-unresolvable="true"/>   Xml程式碼   <b

Android:自定義Application儲存全域性變數

構建app時,總是需要用到一些全域性變數,我們通過自定義的Application訪問。 我們的app就是一個application,啟動application時,系統會建立一個程序ID,所有的Activity就會在此程序上執行。可以在Application建立

Android中Application類用法(整個程式的全域性變數即單例)類似於session

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.test"

Node js的全域性物件全域性變數

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

JS 基礎之全域性變數區域性變數

原文連結:https://github.com/TooBug/javascript.patterns/blob/master/chapter2.markdown 第二章 概要 本章將概要介紹一些編寫高質量JavaScript的最佳實踐、模式和習慣,比如避免全域性變數、使用單var宣告、預快取

static作用有三條全域性變數函式區域性變數https://www.cnblogs.com/liuna/p/7238239.html

在C語言中,static的字面意思很容易把我們匯入歧途,其實它的作用有三條。 (1)先來介紹它的第一條也是最重要的一條:隱藏。 當我們同時編譯多個檔案時,所有未加static字首的全域性變數和函式都具有全域性可見性。為理解這句話,我舉例來說明。我們要同時編譯

在Vue專案中建立檔案儲存全域性變數和方法

在做Vue專案中經常會遇到某些方法或變數、常量需要跨元件呼叫,使用時不能再元件內區域性宣告,這是後就需要有一個地方來單獨的存放這些全域性的變兩或方法,下面我就簡單接介紹一下這個全域性檔案建立的大概流程以及呼叫方法; 第一步:新建一個.vue的檔案來儲存全域性變數或方法;我建立的檔名為global

.net webService儲存全域性變數

遇到坑,然後找到解決方案,我就習慣做個記錄。 情景:通過webservice呼叫一個第三方的庫,在初始化第三方庫的時候需要花費較長時間 目的:希望通過初始化一次,快取下來,下次直接呼叫,而不必每次初始化。 處理思路:在web專案中新增全域性應用程式類(Global.cs),通過其Application_

golang 全域性執行順序先執行全域性變數在執行init

package utils import "fmt" var Age int var Name string // Age Nane 是全域性變數 func init(){ fmt.Println("init 包的初始化 init()。。。") Age = 100

區域性變數全域性變數以及作用範圍

       在寫工程檔案的時候,犯了一個基礎性的錯誤,基礎不牢,地動山搖。所以通過查閱資料回顧了一些相關知識,並記錄下來。防止以後再發生這種慘案。 變數按儲存區域分:全域性變數、靜態全域性變數和靜態區域性變數都存放在記憶體的靜態儲存區域,區域性變數存放在記憶體的棧區。

vue專案中定義並使用 全域性變數全域性函式

一、定義變數,並全域性使用 原理: 1. 單獨新建一個全域性變數模組檔案,模組中定義一些變數初始狀態,用export default 暴露出去。 2. 在main.js中引入,並通過Vue.prototype掛載到vue例項上面

python函式(全域性變數區域性變數作用域遞迴函式高階函式匿名函式)

  1.1函式 1.1.1什麼是函式 函式就是程式實現模組化的基本單元,一般實現某一功能的集合。函式名:就相當於是程式程式碼集合的名稱引數:就是函式運算時需要參與運算的值被稱作為引數函式體:程式的某個功能,進行一系列的邏輯運算return 返回值:函式的返回值能表示函式的執行結果或

fatal error LNK1169: 找到一個或多個多重定義的符號或多個.c/.cpp檔案想同時呼叫定義在.h檔案裡面的全域性變數防止重定義變數問題。

為什麼.h檔案中不能定義全域性變數? 原因: 存在多次建立變數.如果標頭檔案中可以定義全域性變數,那麼每個包含該標頭檔案的檔案裡都會有該全域性變數的定義.因為C語言的include是直接將檔案嵌入到include這個地方的. 解決辦法: ​在標頭檔案使用 extern 來宣告該全域性變

C++程式執行時記憶體佈局之----------區域性變數全域性變數靜態變數函式程式碼new出來的變數

宣告兩點: (1)開發測試環境為VS2010+WindowsXP32位; (2)記憶體佈局指的是虛擬記憶體地址,不是實體地址。   1.測試程式碼 #include <iostream> using namespace std; int g_int_a; i

寫一個函式輸入int型返回整數逆序後的字串。如:輸入123返回“321”。 要求必須用遞迴不能用全域性變數輸入必須是一個引數必須返回字串

看了一下這個文章http://www.codeceo.com/article/alibaba-interview-java.html 順手寫了下 應該符合題目意思吧~~ #include <cstdio> #include <iostream> #i

vue-cli中使用Less全域性變數一次性匯入

1、安裝sass-resources-loader npm install sass-resources-loader --save-dev 2、新增函式 找到 build/utils.js 檔

阿里雲產品物件儲存oss概述有什麼優勢

阿里雲的產品種類繁多,今天讓我們一起來了解下物件儲存(Object Storage Service,簡稱OSS)吧! 詳情介紹:阿里雲物件儲存oss價格及產品詳情頁 什麼是物件儲存呢? 簡單來說,物件儲存OSS是阿里雲提供的海量、安全和高可靠的雲端儲存服務。儲存容量和處理能力的彈