溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

SpringBoot中如何使用監(jiān)聽器

發(fā)布時間:2022-03-15 10:18:44 來源:億速云 閱讀:176 作者:iii 欄目:開發(fā)技術(shù)

今天小編給大家分享一下SpringBoot中如何使用監(jiān)聽器的相關(guān)知識點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

    1.監(jiān)聽器

    web監(jiān)聽器是一張Servlet中特殊的類,它們能幫助開發(fā)者監(jiān)聽web中特定的事件,比如ServletContext,HttpSession,ServletRequest的創(chuàng)建和銷毀;變量的創(chuàng)建、銷毀、和修改等??梢栽谀承﹦幼髑昂笤黾犹幚恚瑢?shí)現(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ù),用于緩存。舉個例子:比如用戶在點(diǎn)擊某個網(wǎng)站的首頁時,一般都會展現(xiàn)出首頁的一些信息,而這些信息基本上或者大部分時間都保持不變的,但是這些信息都是來自數(shù)據(jù)庫,如果用戶的每次點(diǎn)擊,都要從數(shù)據(jù)庫中去獲取數(shù)據(jù)的話,用戶量少還可以接受,如果用戶量非常大的話,這對數(shù)據(jù)庫也是一筆很大的開銷。

    針對這種首頁數(shù)據(jù),大部分都不常更新的話,我們完全可以把它們緩存起來,每次用戶點(diǎn)擊的時候,我們都直接從緩存中拿,這樣既可以提高首頁的訪問速度,又可以降低服務(wù)器的壓力,如果做得更加靈活一點(diǎn),可以再加個定時器,定期的來更新這個首頁緩存,就類似于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(){
            //實(shí)際中會根據(jù)具體的業(yè)務(wù)場景,從數(shù)據(jù)庫中查詢對應(yīng)的信息
            return new User(10,"lyh20","123456");
        }
    }

    然后寫一個監(jiān)聽器,實(shí)現(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ū)ο螅瑢⒉榈降男畔⒎诺絘pplication域中
            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");
        }
    }

    啟動項(xiàng)目,在瀏覽器中輸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)聽器需要實(shí)現(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;
        }
    }

    以上就是“SpringBoot中如何使用監(jiān)聽器”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI