理論上來說,要實現 “如何讓一段代碼在 tomcat 啟動時就被運行” 有很多種方法,我所知道的有兩種: 1. 在 web.xml 里面配置為 listener ; 2. 配置為 Spring 的 bean 。今天因為有同班同學問了這個問題,所以就總結了這兩種方法 o(∩_∩)o
1. 在 web.xml 里面配置為 listener
1 <listener> 2 <listener-class>com.pandaroid.uniqueonline.UniqueOnlineSessionListener</listener-class> 3 </listener>
如上代碼片段配置了一個 listener , 該 listener 中有一個 static 代碼塊:
1 public class UniqueOnlineSessionListener implements HttpSessionListener { 2 static { 3 System.out.println("haha static"); 4 } 5 @Override 6 public void sessionCreated(HttpSessionEvent arg0) { 7 8 } 9 10 @Override 11 public void sessionDestroyed(HttpSessionEvent arg0) { 12 UniqueOnlineRecords.removeUser(arg0.getSession()); 13 } 14 15 }
由於定義為 listener ,所以在 tomcat 啟動時就會初始化,初始化時 static 代碼塊會被執行,於是就達到了我們需要的效果:
從圖中可以看出在 Server 完成啟動前,我們的代碼就執行了,也就實現了“讓一段代碼在 tomcat 啟動時就被運行”。
2. 配置為 Spring 的 bean
這種方式在讀某學長的代碼時看到,於是學了過來。特別要注意的是:使用這種方式時,bean 的 scope 必須設為默認的 singleton 。因為只有這樣,Spring 才會在應用服務器啟動時為我們加載相應的 bean 。
1 <bean id="HiReportService" class="com.pandaroid.hiReport.service.HiReportServiceImpl"> 2 <property name="fileUploadDiskPath" ref="fileupload.disk.path"/> 3 <property name="fileUploadHttpPath" ref="fileupload.http.path"/> 4 <property name="jasperService" ref="JasperService"/> 5 </bean>
上面是項目中 HiReportService 的配置,為了測試,我在相應的 HiReportServiceImpl 類中加入了一段 static 代碼:
1 public class HiReportServiceImpl implements HiReportService { 2 static { 3 System.out.println("Spring bean static !"); 4 } 5 ... 6 }
最終的運行結果如下:
也是順利實現了“讓一段代碼在 tomcat 啟動時就被運行”。
3. 總結
問題的關鍵在於:讓 tomcat 啟動時加載我們的類,加載了,那么必然會運行其中的 static 代碼塊;那么如何讓我們的類在 tomcat 啟動時被加載?使用上述兩種方法即可 o(∩_∩)o
如果有問題或更好的方法,歡迎留言提出和交流,謝謝 o(∩_∩)o