SpringBoot監聽器的心得
目錄
問題描述
各位小夥伴大家好,在做SpringBoot項目的時候,如果是像之前Springmvc或者是Servlet中添加監聽器會出現一些問題,今天我做一個總結,通過實踐得出真諦,接下來看看是不是你也遇見了一樣的問題。
在開發SpringBoot項目的時候,我們如果使用監聽器的註解@WebListener(javax.servlet.annotation.WebListener)
比如我寫了一個Application的監聽器如下:
@WebListener
public class ApplicationtListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("監聽開始");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("監聽結束");
}
}
1、啓動SpringBoot,這個監聽是不被識別的;
2、需要在SpringBoot項目的啓動類上增加一個註解:@ServletComponentScan
/**
* @author Johnny
* @ServletComponentScan 這個註解在獨立的Tomcat中不可以使用
* @category 如果需要使用監聽器,過濾器這樣servlet,需要使用成bean完成
*
*/
@ServletComponentScan
@SpringBootApplication
@MapperScan("com.company.dao")
public class Run {
public static void main(String[] args) {
SpringApplication.run(Run.class, args);
}
}
說明一下:@ServletComponentScan這個註解是用來掃描項目中的Servlet註解的。
可以在項目開啓的時候,監聽器得到觸發,結果如下:
注意,這並不是這篇博客的重點;
鋪墊結束,以上使我們在本地運行的都沒有問題的~
但是,一旦單獨發佈在TOMCAT服務器上,你的這個監聽就不行了呢,也就是說,服務器不支持。
就是害怕這種但是對不對,本地運行的好好的,一到服務器就不行,從8.0換成8.5都不行,然後你該怎麼辦?
往往這時候你會有點慌張:因爲你項目本地好好的,到底服務器上哪裏出現問題了呢?
給大家一個乾貨指導,你看日誌,看Tomcat給你的日誌信息,通過日誌你看到是監聽器創建失敗。這個時候呢,我們就聚焦到監聽器的這個地方來。下面說:
如何將本地和服務器一致,都支持監聽器
問題描述
在SpringBoot項目裏,獨立Tomcat服務器出現的問題如下
在本地跑的很正常的程序,在服務器上跑不動,最奇怪的是有些接口能用,有些不能用,經過多方觀察、
發現用到:servlet、listener和filter的都掛了。
搜了很多資料之後,還是在spring boot 2.01的文檔中找到這麼一句話:
Tip
@ServletComponentScan has no effect in a standalone container, where the container’s builtin
discovery mechanisms are used instead.
翻譯一下就是@ServletComponentScan這個註解在獨立tomcat服務器不可用。
解決方案:
使用@Bean注入的方式
@Component
public class ApplicationtListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("監聽開始");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("監聽結束");
}
}
這塊使用的註解是@Component
同理,如果你是對Session進行監聽,你應該這麼寫:
/**
* @author Johnny
* @category 博客類型監聽SpringBoot實現
*
*/
@Component
public class SessionListener implements HttpSessionListener{
@Autowired
IBlogKindService blogKindService;// 創建業務邏輯對象
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("監聽器工作:監聽session,將所有的博客類型放到作用域中");
// 將 ApplicationContext 轉化爲 WebApplicationContext
HttpSession session = se.getSession();
// 得到博客類型列表集合
List<BlogKind> blogKindList = blogKindService.findList();
// servletContext設置值
session.setAttribute("blogKindList", blogKindList);
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("監聽器工作:銷燬session");
}
}
對於組件當中需要注入其他組件,你就使用@Autowired這個註解就好。
以上代碼都親手驗證過的,所以小夥伴可以參考我的這個解決方案。
SpringBoot中監聽器的其實是有一個別的推薦的:ApplicationListener(org.springframework.context.ApplicationListener)
如果你要使用Application監聽,可以這麼做:
/**
* @author Johnny
* @category 博客類型監聽SpringBoot實現
*
*/
@Component
public class BlogKinderListener2 implements ApplicationListener<ApplicationStartedEvent> {
@Autowired
IBlogKindService blogKindService;// 創建業務邏輯對象
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
System.out.println("監聽器工作:監聽application,將所有的博客類型放到作用域中");
// 將 ApplicationContext 轉化爲 WebApplicationContext
WebApplicationContext webApplicationContext = (WebApplicationContext) event.getApplicationContext();
// 從 webApplicationContext中獲取servletContext
ServletContext servletContext = webApplicationContext.getServletContext();
List<BlogKind> blogKindList = blogKindService.findList(); // 得到博客類型列表集合
servletContext.setAttribute("blogKindList", blogKindList);// servletContext設置值
}
}
最後:在啓動類裏面去掉了@ServletComponentScan這個註解,本地和獨立Tomcat訪問都是可以的。
大功告成
總結:
在SpringBoot中,其實這個框架更多的希望你直接使用Spring框架中的註解,同時也爲你簡化開發的代碼:
核心問題:監聽器,過濾器其實也都是組件,那麼使用這些東西直接當做普通bean一樣注入到容器裏面就可以。
具體操作:
- 在“監聽器,過濾器”上面註解@Component
- 實現對應的接口(Application接口,Session接口等)
- @ServletComponentScan這個註解在獨立tomcat服務器不可用
完成。
覺得有點用記得給我點贊哦!
這篇文章就到這裏啦,如果覺得有收穫的話,不妨給一個贊喔;文章中涉及的內容肯定是不全面的,歡迎大家評論區留言補充。