SpringBoot中使用監(jiān)聽器的方法詳解
1.監(jiān)聽器
web監(jiān)聽器是一張Servlet中特殊的類,它們能幫助開發(fā)者監(jiān)聽web中特定的事件,比如ServletContext,HttpSession,ServletRequest的創(chuàng)建和銷毀;變量的創(chuàng)建、銷毀、和修改等??梢栽谀承﹦幼髑昂笤黾犹幚?,實現(xiàn)監(jiān)控
2.SpringBoot中監(jiān)聽器的使用
web監(jiān)聽器的使用場景很多,比如監(jiān)聽servlet上下文用來初始化一些數(shù)據(jù)、監(jiān)聽http session用來獲取當(dāng)前在線的人數(shù)、監(jiān)聽客戶端請求的servletrequest對象來獲取用戶的訪問信息等。
2.1 監(jiān)聽Servlet上下文對象
監(jiān)聽Servlet上下文對象可以用來初始化數(shù)據(jù),用于緩存。舉個例子:比如用戶在點擊某個網(wǎng)站的首頁時,一般都會展現(xiàn)出首頁的一些信息,而這些信息基本上或者大部分時間都保持不變的,但是這些信息都是來自數(shù)據(jù)庫,如果用戶的每次點擊,都要從數(shù)據(jù)庫中去獲取數(shù)據(jù)的話,用戶量少還可以接受,如果用戶量非常大的話,這對數(shù)據(jù)庫也是一筆很大的開銷。
針對這種首頁數(shù)據(jù),大部分都不常更新的話,我們完全可以把它們緩存起來,每次用戶點擊的時候,我們都直接從緩存中拿,這樣既可以提高首頁的訪問速度,又可以降低服務(wù)器的壓力,如果做得更加靈活一點,可以再加個定時器,定期的來更新這個首頁緩存,就類似于csdn個人博客首頁中排名的變化一樣
下面我們針對這個功能,來寫一個Service,模擬一下從數(shù)據(jù)庫查詢數(shù)據(jù):
package com.example.springdemo1.service; import com.example.springdemo1.pojo.User; import org.springframework.stereotype.Service; @Service public class UserService2 { public User getUser(){ //實際中會根據(jù)具體的業(yè)務(wù)場景,從數(shù)據(jù)庫中查詢對應(yīng)的信息 return new User(10,"lyh10","123456"); } }
然后寫一個監(jiān)聽器,實現(xiàn)ApplicationListener接口,重寫onApplicationEvent方法,將ContextRefreshedEvent對象傳進(jìn)去,如果我們想在加載或刷新應(yīng)用上下文時,也重新刷新下我們預(yù)加載的資源,就可以通過監(jiān)聽ContextRefreshedEvent來做這樣的事情,如下:
package com.example.springdemo1.util; import com.example.springdemo1.pojo.User; import com.example.springdemo1.service.UserService2; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.stereotype.Component; import javax.servlet.ServletContext; @Component public class MyServletContextListener implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) { //先獲取到application上下文 ApplicationContext applicationContext = contextRefreshedEvent.getApplicationContext(); //獲取對應(yīng)的Service UserService2 userService2 = applicationContext.getBean(UserService2.class); User user = userService2.getUser(); //獲取application域?qū)ο?,將查到的信息放到application域中 ServletContext application = applicationContext.getBean(ServletContext.class); application.setAttribute("user",user); } }
首先通過contextRefreshedEvent來獲取application上下文,再通過application上下文來獲取UserService這個bean,然后再調(diào)用自己的業(yè)務(wù)代碼獲取相應(yīng)的數(shù)據(jù),最后存儲到application域中,這樣前端在請求相應(yīng)數(shù)據(jù)的時候,我們就可以直接從application域中獲取信息,減少數(shù)據(jù)庫的壓力,下面寫一個controller直接從application域中獲取user信息來測試一下
package com.example.springdemo1.controller; import com.example.springdemo1.pojo.User; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @RestController @RequestMapping("/testListener") public class testController12 { @GetMapping("/user") public User getUser(HttpServletRequest request){ ServletContext application = request.getServletContext(); return (User)application.getAttribute("user"); } }
啟動項目,在瀏覽器中輸http://localhost:8082/testListener/user
測試一下即可,如果正常返回user信息,那么說明數(shù)據(jù)已經(jīng)緩存成功,不過application這種事緩存在內(nèi)存中,對內(nèi)存會有消耗。
2.2 監(jiān)聽HTTP會話Session對象
監(jiān)聽器還有一個比較常用的地方就是用來監(jiān)聽session對象,來獲取在線用戶數(shù)量。
package com.example.springdemo1.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; @Component public class MyHttpSessionListener implements HttpSessionListener { private static Logger logger = LoggerFactory.getLogger(MyHttpSessionListener.class); //記錄在線的用戶數(shù)量 public Integer count = 0; @Override public synchronized void sessionCreated(HttpSessionEvent httpSessionEvent){ logger.info("新用戶上線了"); count++; httpSessionEvent.getSession().getServletContext().setAttribute("count",count); } @Override public synchronized void sessionDestroyed(HttpSessionEvent httpSessionEvent){ logger.info("用戶下線了"); count--; httpSessionEvent.getSession().getServletContext().setAttribute("count",count); } }
可以看出,首先該監(jiān)聽器需要實現(xiàn)HttpSessionListener接口,然后重寫sessionCreated和sessionDestroyed方法,在sessionCreated方法中傳遞一個httpSessionEvent對象,然后將當(dāng)前session中的用戶數(shù)量加一,sessionDestroyed方法方法剛好相反,不再贅述,然后我們再寫一個controller來測試一下:
package com.example.springdemo1.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; @RestController @RequestMapping("/testMyListener") public class testController13 { /** * 獲取當(dāng)前在線人數(shù),該方法有bug * @param request * @return */ @GetMapping("/total") public String getTotalUser(HttpServletRequest request) { Integer count = (Integer) request.getSession().getServletContext().getAttribute("count"); return "當(dāng)前在線人數(shù):" + count; } }
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
JVM性能調(diào)優(yōu)之運(yùn)行時參數(shù)小結(jié)
jvm是java的運(yùn)行環(huán)境,在jvm中有很多的參數(shù)可以進(jìn)行設(shè)置,本文主要介紹了JVM性能調(diào)優(yōu)之運(yùn)行時參數(shù)小結(jié),具有一定的參考價值,感興趣的可以了解一下2024-04-04JDK13.0.1安裝與環(huán)境變量的配置教程圖文詳解(Win10平臺為例)
這篇文章主要介紹了JDK13.0.1安裝與環(huán)境變量的配置教程圖文詳解(Win10平臺為例),本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2020-01-01Java在指定路徑上創(chuàng)建文件提示不存在解決方法
在本篇文章里小編給大家整理的是一篇關(guān)于Java在指定路徑上創(chuàng)建文件提示不存在解決方法,有需要的朋友們可以參考下。2020-02-02