Spring配置文件是集成了Spring框架的项目的核心,引擎从哪里开始,中间都执行了哪些操作,小谈一下它的执行流程。
容器先是加载web .xml
接着是applicationContext.xml在web .xml里的注册
一种方法是加入ContextLoaderServlet这个servlet
- < context-param >
- < param-name > contextConfigLocation param-name >
- < param-value > /WEB -INF/applicationContext.xml param-value >
- context-param >
- < servlet >
- < servlet-name > context servlet-name >
- < servlet-class >
- org.springframework.web .context.ContextLoaderServlet
- servlet-class >
- < load-on-startup > 0 load-on-startup >
- servlet >
contextConfigLocation
/WEB
-INF/applicationContext.xml
context
org.springframework.web
.context.ContextLoaderServlet
0
还有一种是添加ContextLoaderListener这个监听器
- < context-param >
- < param-name > contextConfigLocation param-name >
- < param-value > /WEB -INF/applicationContext.xml param-value >
- context-param >
-
- < listener >
- < listener-class > org.springframework.web .context.ContextLoaderListener listener-class >
- listener >
contextConfigLocation
/WEB
-INF/applicationContext.xml
org.springframework.web
.context.ContextLoaderListener
下面是ContextLoaderServlet源代码
- package org.springframework.web .context;
-
- import java.io.IOException;
-
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- public class ContextLoaderServlet extends HttpServlet {
-
- private ContextLoader contextLoader ;
-
-
-
-
-
-
- public void init() throws ServletException {
- this .contextLoader = createContextLoader();
- this .contextLoader .initWebApplicationContext(getServletContext());
- }
-
-
-
- protected ContextLoader createContextLoader() {
- return new ContextLoader ();
- }
-
-
-
-
-
- public ContextLoader getContextLoader() {
- return this .contextLoader ;
- }
-
-
-
-
-
- public void destroy() {
- if ( this .contextLoader != null ) {
- this .contextLoader .closeWebApplicationContext(getServletContext());
- }
- }
-
-
-
-
-
-
-
- public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
- getServletContext().log(
- "Attempt to call service method on ContextLoaderServlet as [" +
- request.getRequestURI() + "] was ignored" );
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- }
-
-
- public String getServletInfo() {
- return "ContextLoaderServlet for Servlet API 2.3 " +
- "(deprecated in favor of ContextLoaderListener for Servlet API 2.4)" ;
- }
-
- }
package org.springframework.web
.context;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ContextLoaderServlet extends HttpServlet {
private ContextLoader
contextLoader
;
/**
* Initialize the root web
application context.
*/
public void init() throws ServletException {
this.contextLoader
= createContextLoader();
this.contextLoader
.initWebApplicationContext(getServletContext());
} /**
* Create the ContextLoader
to use. Can be overridden in
subclasses.
* @return the new ContextLoader
*/
protected ContextLoader
createContextLoader() {
return new ContextLoader
();
}
/**
* Return the ContextLoader
used by this servlet.
* @return the current ContextLoader
*/
public ContextLoader
getContextLoader() {
return this.contextLoader
;
}
/**
* Close the root web
application context.
*/
public void destroy() {
if (this.contextLoader
!= null) {
this.contextLoader
.closeWebApplicationContext(getServletContext());
}
}
/**
* This should never even be called since no mapping to this servlet should
* ever be created in
web
.xml. That's why a correctly invoked Servlet 2.3
* listener is much more appropriate for initialization work ;-)
*/
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
getServletContext().log(
"Attempt to call service method on ContextLoaderServlet as [" +
request.getRequestURI() + "] was ignored");
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
}
public String getServletInfo() {
return "ContextLoaderServlet for Servlet API 2.3 " +
"(deprecated in
favor of ContextLoaderListener for Servlet API 2.4)";
}
}
ContextLoaderListener源代码
- package org.springframework.web .context;
-
- import javax.servlet.ServletContextEvent;
- import javax.servlet.ServletContextListener;
-
- public class ContextLoaderListener implements ServletContextListener {
-
- private ContextLoader contextLoader ;
-
-
-
-
-
- public void contextInitialized(ServletContextEvent event) {
- this .contextLoader = createContextLoader();
- this .contextLoader .initWebApplicationContext(event.getServletContext());
- }
-
-
-
-
-
- protected ContextLoader createContextLoader() {
- return new ContextLoader ();
- }
-
-
-
-
-
- public ContextLoader getContextLoader() {
- return this .contextLoader ;
- }
-
-
-
-
-
- public void contextDestroyed(ServletContextEvent event) {
- if ( this .contextLoader != null ) {
- this .contextLoader .closeWebApplicationContext(event.getServletContext());
- }
- }
-
- }
package org.springframework.web
.context;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ContextLoaderListener implements ServletContextListener {
private ContextLoader
contextLoader
;
/**
* Initialize the root web
application context.
*/
public void contextInitialized(ServletContextEvent event) {
this.contextLoader
= createContextLoader();
this.contextLoader
.initWebApplicationContext(event.getServletContext());
}
/**
* Create the ContextLoader
to use. Can be overridden in
subclasses.
* @return the new ContextLoader
*/
protected ContextLoader
createContextLoader() {
return new ContextLoader
();
}
/**
* Return the ContextLoader
used by this listener.
* @return the current ContextLoader
*/
public ContextLoader
getContextLoader() {
return this.contextLoader
;
}
/**
* Close the root web
application context.
*/
public void contextDestroyed(ServletContextEvent event) {
if (this.contextLoader
!= null) {
this.contextLoader
.closeWebApplicationContext(event.getServletContext());
}
}
}
以上都提到了ContextLoader 这个类
- package org.springframework.web .context;
-
- public class ContextLoader {
-
- public static final String CONTEXT_CLASS_PARAM = "contextClass" ;
-
- public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation" ;
-
- public static final String LOCATOR_FACTORY_SELECTOR_PARAM = "locatorFactorySelector" ;
-
- public static final String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey" ;
-
- private static final String DEFAULT_STRATEGIES_PATH = "ContextLoader .properties" ;
-
-
- private static final Properties defaultStrategies;
-
- static {
- try {
- ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader . class );
- defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
- }
- catch (IOException ex) {
- throw new IllegalStateException( "Could not load 'ContextLoader .properties': " + ex.getMessage());
- }
- }
-
-
- private static final Log logger = LogFactory.getLog(ContextLoader . class );
-
- private static final Map currentContextPerThread = CollectionFactory.createConcurrentMapIfPossible( 1 );
-
- private WebApplicationContext context;
-
- private BeanFactoryReference parentContextRef;
-
- public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
-
- throws IllegalStateException, BeansException {
-
- if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null ) {
- throw new IllegalStateException(
- "Cannot initialize context because there is already a root application context present - " +
- "check whether you have multiple ContextLoader * definitions in your web .xml!" );
- }
-
- servletContext.log("Initializing Spring root WebApplicationContext" );
- if (logger.isInfoEnabled()) {
- logger.info("Root WebApplicationContext: initialization started" );
- }
- long startTime = System.currentTimeMillis();
-
- try {
-
- ApplicationContext parent = loadParentContext(servletContext);
-
-
-
- this .context = createWebApplicationContext(servletContext, parent);
- servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this .context);
- currentContextPerThread.put(Thread.currentThread().getContextClassLoader(), this .context);
-
- if (logger.isDebugEnabled()) {
- logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +
- WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]" );
- }
- if (logger.isInfoEnabled()) {
- long elapsedTime = System.currentTimeMillis() - startTime;
- logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms" );
- }
-
- return this .context;
- }
- catch (RuntimeException ex) {
- logger.error("Context initialization failed" , ex);
- servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
- throw ex;
- }
- catch (Error err) {
- logger.error("Context initialization failed" , err);
- servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
- throw err;
- }
- }
-
- protected WebApplicationContext createWebApplicationContext(
- ServletContext servletContext, ApplicationContext parent) throws BeansException {
-
- Class contextClass = determineContextClass(servletContext);
- if (!ConfigurableWebApplicationContext. class .isAssignableFrom(contextClass)) {
- throw new ApplicationContextException( "Custom context class [" + contextClass.getName() +
- "] is not of type [" + ConfigurableWebApplicationContext. class .getName() + "]" );
- }
-
- ConfigurableWebApplicationContext wac =
- (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
- wac.setParent(parent);
- wac.setServletContext(servletContext);
- "color: rgb(0, 0, 0);" >wac.setConfigLocation(servletContext.getInitParameter(CONFIG_LOCATION_PARAM));
-
-
-
-
-
-
- customizeContext(servletContext, wac);
- wac.refresh();
-
- return wac;
- }
-
- protected Class determineContextClass(ServletContext servletContext) throws ApplicationContextException {
- String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
- if (contextClassName != null ) {
- try {
- return ClassUtils.forName(contextClassName);
- }
- catch (ClassNotFoundException ex) {
- throw new ApplicationContextException(
- "Failed to load custom context class [" + contextClassName + "]" , ex);
- }
- }
- else {
- contextClassName = defaultStrategies.getProperty(WebApplicationContext.class .getName());
- try {
- return ClassUtils.forName(contextClassName, ContextLoader . class .getClassLoader());
- }
- catch (ClassNotFoundException ex) {
- throw new ApplicationContextException(
- "Failed to load default context class [" + contextClassName + "]" , ex);
- }
- }
- }
-
- protected void customizeContext(
- ServletContext servletContext, ConfigurableWebApplicationContext applicationContext) {
- }
-
- protected ApplicationContext loadParentContext(ServletContext servletContext)
- throws BeansException {
-
- ApplicationContext parentContext = null ;
- String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM);
- String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM);
-
- if (parentContextKey != null ) {
-
- BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);
- if (logger.isDebugEnabled()) {
- logger.debug("Getting parent context definition: using parent context key of '" +
- parentContextKey + "' with BeanFactoryLocator" );
- }
- this .parentContextRef = locator.useBeanFactory(parentContextKey);
- parentContext = (ApplicationContext) this .parentContextRef.getFactory();
- }
-
- return parentContext;
- }
-
- public void closeWebApplicationContext(ServletContext servletContext) {
- servletContext.log("Closing Spring root WebApplicationContext" );
- try {
- if ( this .context instanceof ConfigurableWebApplicationContext) {
- ((ConfigurableWebApplicationContext) this .context).close();
- }
- }
- finally {
- currentContextPerThread.remove(Thread.currentThread().getContextClassLoader());
- servletContext.removeAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
- if ( this .parentContextRef != null ) {
- this .parentContextRef.release();
- }
- }
- }
-
-
- public static WebApplicationContext getCurrentWebApplicationContext() {
- return (WebApplicationContext) currentContextPerThread.get(Thread.currentThread().getContextClassLoader());
- }
-
- }
package org.springframework.web
.context;
public class ContextLoader
{
public static final String CONTEXT_CLASS_PARAM = "contextClass";
public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
public static final String LOCATOR_FACTORY_SELECTOR_PARAM = "locatorFactorySelector";
public static final String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey";
private static final String DEFAULT_STRATEGIES_PATH = "ContextLoader
.properties";
private static final Properties defaultStrategies;
static {
try {
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader
.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException("Could not load 'ContextLoader
.properties': " + ex.getMessage());
}
}
private static final Log logger = LogFactory.getLog(ContextLoader
.class);
private static final Map currentContextPerThread = CollectionFactory.createConcurrentMapIfPossible(1);
private WebApplicationContext context;
private BeanFactoryReference parentContextRef;
public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
throws IllegalStateException, BeansException {
if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
throw new IllegalStateException(
"Cannot initialize context because there is already a root application context present - " +
"check
whether
you
have
multiple
ContextLoader
* definitions
in
your
web
.xml!");
}
servletContext.log("Initializing Spring root WebApplicationContext");
if (logger.isInfoEnabled()) {
logger.info("Root WebApplicationContext: initialization started");
}
long startTime = System.currentTimeMillis();
try {
// Determine parent for root web
application context, if any.
ApplicationContext parent = loadParentContext(servletContext);
// Store context in
local instance variable, to guarantee that
// it is available on ServletContext shutdown.
this.context = createWebApplicationContext(servletContext, parent);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
currentContextPerThread.put(Thread.currentThread().getContextClassLoader(), this.context);
if (logger.isDebugEnabled()) {
logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
}
if (logger.isInfoEnabled()) {
long elapsedTime = System.currentTimeMillis() - startTime;
logger.info("Root WebApplicationContext: initialization completed in
" + elapsedTime + " ms");
}
return this.context;
}
catch (RuntimeException ex) {
logger.error("Context initialization failed", ex);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
throw ex;
}
catch (Error err) {
logger.error("Context initialization failed", err);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
throw err;
}
}
protected WebApplicationContext createWebApplicationContext(
ServletContext servletContext, ApplicationContext parent) throws BeansException {
Class contextClass = determineContextClass(servletContext);
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
"] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
}
ConfigurableWebApplicationContext wac =
(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
wac.setParent(parent);
wac.setServletContext(servletContext);
wac.setConfigLocation(servletContext.getInitParameter(CONFIG_LOCATION_PARAM));
customizeContext(servletContext, wac);
wac.refresh();
return wac;
}
protected Class determineContextClass(ServletContext servletContext)