1. 程式人生 > >Spring MVC讓Web容器啟動時自動執行程式碼

Spring MVC讓Web容器啟動時自動執行程式碼

在web.xml中,對於每一個servlet都有一個load-on-startup屬性,其值為一個整數。若該值為0或正整數,則當Web容器啟動時,該servlet會自動載入,並呼叫其中的init()方法,整數值越小,載入的優先順序越高;若值為負數或未指定,則該servlet只有被選擇時才會被載入。

因此,可以考慮通過Servlet進行實現。並配置web.xml檔案,令應用容器在啟動時就自動載入一個servlet並執行其中的init()方法。servlet程式如下:

package com.xxx.action;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

public class AutoRunServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	
	public void init() throws ServletException {
        	System.out.println("Servlet has been initialized!");
	}
}

對應web.xml配置如下,這裡優先順序設為10:
<servlet>
        <servlet-name>autoRunServlet</servlet-name>
        <servlet-class>com.xxx.action.AutoRunServlet</servlet-class>
        <load-on-startup>10</load-on-startup>
    </servlet>

這樣即可實現servlet的自動載入。那麼如果在專案中使用了Spring MVC框架,並且在初始化時需要整合Spring,或是需要用到在Spring中配置好的bean以及Spring MVC的controller,該如何處理呢?
我們知道,Spring通過ApplicationContext(通常翻譯成上下文)來對bean進行配置與管理,因此若要與Spring整合,使用Spring的bean,必須先拿到相關的上下文,然後通過上下文獲取bean。大致思路如下:

ApplicationContext ac = ... //獲取ApplicationContext
ExampleBean bean = (ExampleBean)ac.getBean(ExampleBean.class);//假設要獲取的bean型別為ExampleBean

在Spring MVC中,這個ApplicationContext叫做WebApplicationContext,它直接繼承於ApplicationContext。Spring MVC的WebApplicationContext分為兩種,一種是Spring建立的一個全域性WebApplicationContext上下文,稱為根上下文,注意這個上下文是Spring的,不是Spring MVC的,因此不包含Spring MVC的資訊(如Spring MVC的controller等)。若在web.xml中配置了context-param,則其對應的xml對應的配置為根上下文。該上下文儲存在ServletContext中(也叫application,Servlet的一個鍵值對空間,類似於session,但是與session的區別是ServletContext由所有客戶端共用,而session只屬於一個客戶端)的一個鍵中,該鍵的名字為WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE屬性的值,可以通過很多方法取出,下面會詳述。另一種是Spring MVC的DispatcherServlet(Spring MVC的Servlet,可以擁有多個)載入後自己的上下文,除了擁有根上下文的所有內容,還有Spring MVC的資訊。這樣的上下文同樣儲存在ServletContext中,key為"org.springframework.web.servlet.FrameworkServlet.CONTEXT."+servlet名稱。
知道了上下文存在哪裡,我們的思路也就明朗了。只要拿到這個ServletContext,就可以通過key得到對應的上下文,繼而得到bean。


考慮如下web.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath*:service-context.xml</param-value>
	</context-param>
	
	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

從上述程式碼的第19行可以看出,在該工程下只有一個Spring MVC DispatcherServlet,其名稱為appServlet,那麼我們就可以確定Spring MVC的上下文儲存在org.springframework.web.servlet.FrameworkServlet.CONTEXT.appServlet中。獲取方法如下:
ServletContext sc = getServletContext();
WebApplicationContext wac = (WebApplicationContext)sc.getAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.appServlet");
ExampleSpringMVCBean bean = ac.getBean(ExampleSpringMVCBean.class);

而對於Spring的根上下文,bean的獲取方式就有很多種了。通過根上下文,也可以拿到ServletContext相關資訊。
ServletContext sc = getServletContext();  
WebApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
ExampleBean bean = (ExampleBean)ac.getBean(ExampleBean.class);

ServletContext sc = getServletContext();  
WebApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(sc);
ExampleBean bean = (ExampleBean)ac.getBean(ExampleBean.class);//假設要獲取的bean型別為ExampleBean

WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
ExampleBean bean = (ExampleBean)ac.getBean(ExampleBean.class);

ServletContext sc = getServletContext();
WebApplicationContext wac = (WebApplicationContext)sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
ExampleBean bean = (ExampleBean)ac.getBean(ExampleBean.class);



最終程式碼:
public class AutoRunServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	
	public void init() throws ServletException {
        	ServletContext sc = getServletContext();
 			WebApplicationContext wac = (WebApplicationContext)sc.getAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.appServlet");
			ExampleSpringMVCBean bean = ac.getBean(ExampleSpringMVCBean.class);
			WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
			ExampleBean bean = (ExampleBean)ac.getBean(ExampleBean.class);
	}
}


相關推薦

Spring MVCWeb容器啟動自動執行程式碼

在web.xml中,對於每一個servlet都有一個load-on-startup屬性,其值為一個整數。若該值為0或正整數,則當Web容器啟動時,該servlet會自動載入,並呼叫其中的init()方

【Java】—— java Web 啟動自動執行程式碼的幾種方式(總有些程式碼需要在虛擬機器啟動執行)

Web容器啟動後執行程式碼的幾種方式其執行順序為:4===>5===>1===>2===>3即指定init-method的Bean開始執行接著實現Spring的Bean後置處理器開始執行然後是Servlet的監聽器執行再接下來是Servlet的過濾器執

實現tomcat啟動自動執行程式碼

方法1:tomcat 自動執行servlet 寫一個servlet,在init()方法中寫好想要執行的程式,程式如下: eclipse新建一個web\Dynamic Web Project , name = myweb1 , 把tomcat中的 servlet-api.jar複製到lib中,新建一個類MyS

springweb容器啟動執行初始化方法(四種方式)

需求:在tomcat啟動時開啟一個定時任務,或初始化slor索引 想法:容器啟動時執行方法,最容易想到的就是servlet中可以配置load-on-startup,設定一個正整數也就可以隨容器一起啟動。 問題:上面的方法很好,但是由於定時任務需要去操作資料庫,而專案

SpringWeb容器啟動執行初始化方法

需求:在tomcat啟動時開啟一個定時任務。 想法:容器啟動時執行方法,最容易想到的就是servlet中可以配置load-on-startup,設定一個正整數也就可以隨容器一起啟動。 問題:上面的方法很好,但是由於定時任務需要去操作資料庫,而專案採用了spring的依賴注入來管理物件,而serv

Web容器啟動載入Spring分析

ContextLoaderListener類實現了javax.servlet.ServletContextListener介面並且繼承了org.springframework.web.context.ContextLoader類。ServletContextListener事件類是Web容器的一部分,處理We

java springMVC web容器啟動初始化方法

需求:在tomcat服務啟動時初始化一些引數。 想法:容器啟動時執行方法,最容易想到的就是servlet中可以配置load-on-startup,設定一個正整數也就可以隨容器一起啟動。 解決方案:Spring提供了當一個Bean初始化後執行方法

IDEA 下spring mvcweb 程式啟動報錯找不到類:org.springframework.web.context.ContextLoaderListener等問題

當初看見這個以為自己那個地方出現了什麼毛病。所以多建立了幾個程式,卻發現一直都是啟動不了啟動失敗22-Mar-2018 19:50:30.426 嚴重 [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.Sta

Web服務啟動自動載入Servlet,並執行service處理

轉自:http://lives.iteye.com/blog/1141121 自動載入Servlet的方法介紹:  在web.xml這樣定義一個servlet: <servlet> <servlet-name>t1</servlet-name&

web專案啟動自動啟動mysql資料庫

背景介紹:    最近在學習spring,看到容器事件ApplicationEvent時,突然想到一個問題,因為在本地搭建了一套學習環境,每次啟動web專案時都要首先手動啟動mysql,有時忘了啟動mysql時,控制檯就會丟擲資料庫連線失敗的異常資訊,所以就在想,能否利用容器

Web服務啟動自動載入Servlet,並執行service處理 監聽處理

自動載入servlet,非常棒的方式 這個有什麼作用呢? 自動載入我們的Servlet,之前我也是覺得這個東西,非常的簡單嘛。自動載入就自動載入啦。有什麼覺得可以理解的呢? 其實這裡面的東西非常的深入的哦,好好的瞭解哈,非常的有必要哦。為啥這麼說呢?我們

Linux系統啟動過程自動執行自己編寫的指令碼

在Linux系統,/etc路徑下,一般有以下目錄: rc0.d rc1.d rc2.d rc3.d rc4.d rc5.d rc6.d 在系統啟動的過程中,會按照rc0.d~rc6.d的順序執行這些目錄下的指令碼,如果想要系統啟動過程中執行自己編寫的指令碼,只需要將指令

web專案啟動執行某個方法

1.監聽(Listener) web檔案新增 <listener>      <listener-class>cn.ro.common.InitListener</listener-class>   </l

Docker-mysql啟動自動執行SQL

說明 在用docker建立mysql容器的時,有時候我們期望容器啟動後資料庫和表會自動構建,初始化資料也已自動錄入,也就是說容器啟動後我們就能直接連上容器中的資料庫,使用其中的資料了。自動執行SQL這一過程存在於第一次使用映象構建容器時,下一次restart容器時則不會存在

SpringBoot專案啟動自動執行指定方法

在SpringBoot中,有兩種介面方式實現啟動執行,分別是ApplicationRunner和CommandLineRunner,除了可接受引數不同,其他的大同小異 ApplicationRunner : import org.springfr

Spring mvc + mybatis web專案當系統啟動自動呼叫某個方法

1、新增WebContextListener.java2、檔案內容package com.pt.controller.listener; import javax.servlet.ServletCon

springWeb專案啟動自動載入方法及web專案啟動不能獲得spring的bean的解決方式

方式一:利用註解的方式和構造方法 @Service("testService") public class TestService { @Autowired private Service service; /** * spring在初始化bea

Spring MVCWeb環境(一):IOC容器Spring MVC中的啟動

            在原書的閱讀中我們可以看到,Spring並不是天生就能在Web容器中起作用的。我們同樣需要把我們的IoC容器手動新增到Web容器中,也就是在web.xml檔案中配置一些基礎的類比如DispatcherServlet,ContextLoaderListe

spring mvcWeb.xml中自動掃描Spring的配置檔案及resourceclasspath*:與classpath:的區別

首先在web.xml中配置監聽器listener,讓spring進行自動獲取。具體加入的程式碼如下: <listener><listener-class>org.springframework.web.context.ContextLoad

Web應用啟動,後臺自動啟動一個執行緒(轉)

原文:http://blog.sina.com.cn/s/blog_6810dfc20101ipzq.html Web應用啟動時,後臺自動啟動一個執行緒   (1)前言     前幾天,manager問道一個問題:能不能實現類似於cro