web.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <context-param>
<param-name>webAppRootKey</param-name>
<param-value>task.root</param-value>
</context-param>
<!-- 定义SPRING配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/taskContext*.xml</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<!-- 定义LOG4J监听器 -->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- 定义SPRING监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
|
进入contextLoaderListener看看到底加载时做了甚么
==>org.springframework.web.context.ContextLoaderListener
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| publicclass ContextLoaderListener implements ServletContextListener {
private ContextLoader contextLoader;
publicvoid contextInitialized(ServletContextEvent event) {
this.contextLoader = createContextLoader();
this.contextLoader.initWebApplicationContext(event.getServletContext());
}
protected ContextLoader createContextLoader() {returnnew ContextLoader();
}
public ContextLoader getContextLoader() {return contextLoader;
}
publicvoid contextDestroyed(ServletContextEvent event) {if (this.contextLoader != null) {
this.contextLoader.closeWebApplicationContext(event.getServletContext());
}}
} |
看一下是怎么来初始化webapplicationContext的
==>contextLoader.initWebApplicationContext
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
throws IllegalStateException, BeansException {
if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {thrownew IllegalStateException(
"Cannot initialize context because there is already a root application context
present - " +"check whether you have multiple ContextLoader* definitions in your web.xml!");
}
long startTime = System.currentTimeMillis();
if (logger.isInfoEnabled()) {
logger.info("Root WebApplicationContext: initialization started");
}
servletContext.log("Loading Spring root WebApplicationContext");
try{
ApplicationContext parent = loadParentContext(servletContext);
this.context = createWebApplicationContext(servletContext, parent);
servletContext.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
if (logger.isInfoEnabled()) {
logger.info("Using context class [" + this.context.getClass().getName() +
"] for root WebApplicationContext");
}if (logger.isDebugEnabled()) {
logger.debug("Published root WebApplicationContext [" + this.context +
"] 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;
}} |
==>contextLoader.createWebApplicationContext(servletContext, parent);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| protected WebApplicationContext createWebApplicationContext(
ServletContext servletContext, ApplicationContext parent) throws BeansException {
Class contextClass = determineContextClass(servletContext);
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {thrownew ApplicationContextException("Custom context class [" + contextClass.getName() +
"] is not of type ConfigurableWebApplicationContext");
}
ConfigurableWebApplicationContext wac =
(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
wac.setParent(parent);
wac.setServletContext(servletContext);
String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
if (configLocation != null) {
wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,
ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
}
wac.refresh();
return wac;
} |
==>contextLoader.determineContextClass(servletContext);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| 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) {thrownew ApplicationContextException(
"Failed to load custom context class [" + contextClassName + "]", ex);
}}else{
contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
try{return ClassUtils.forName(contextClassName);
}catch (ClassNotFoundException ex) {thrownew ApplicationContextException(
"Failed to load default context class [" + contextClassName + "]", ex);
}}} |
SPRING上下文默认的策略是甚么呢?
==>contextLoader.defaultStrategies
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| privatestaticfinal Properties defaultStrategies;
static{try{
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}catch (IOException ex) {thrownew IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());
}} |
找到同级目录下的配置文件
==>ContextLoader.properties
1 2 3 4 5 6 7 8
| # Default WebApplicationContext implementation classfor ContextLoader.
# Used as fallback when no explicit context implementation has been specified as context-param.
# Not meant to be customized by application developers.
#默认的WebApplicationContext为org.springframework.web.context.support.XmlWebApplicationContext
org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext
|
==>org.springframework.web.context.support.XmlWebApplicationContext
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| publicclass XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {
publicstaticfinal String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
publicstaticfinal String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";
publicstaticfinal String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";
protectedvoid loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
protectedvoid initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {}
protectedvoid loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
String[] configLocations = getConfigLocations();
if (configLocations != null) {for (int i = 0; i < configLocations.length; i++) {
reader.loadBeanDefinitions(configLocations[i]);
}}}
protected String[] getDefaultConfigLocations() {if (getNamespace() != null) {returnnew String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() +
DEFAULT_CONFIG_LOCATION_SUFFIX};
}else{returnnew String[] {DEFAULT_CONFIG_LOCATION};
}} |
==>AbstractBeanDefinitionReader.loadBeanDefinitions()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| publicint loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader == null) {thrownew BeanDefinitionStoreException(
"Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
}
if (resourceLoader instanceof ResourcePatternResolver) {try{
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
int loadCount = loadBeanDefinitions(resources);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
}return loadCount;
}catch (IOException ex) {thrownew BeanDefinitionStoreException(
"Could not resolve bean definition resource pattern [" + location + "]", ex);
}}else{
Resource resource = resourceLoader.getResource(location);
int loadCount = loadBeanDefinitions(resource);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
}return loadCount;
}} |
这个是其中一个ResourceLoader的实现
==>PathMatchingResourcePatternResolver.getResources(String locationPattern);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public Resource[] getResources(String locationPattern) throws IOException {
Assert.notNull(locationPattern, "Location pattern must not be null");
if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {return findPathMatchingResources(locationPattern);
}else{return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
}}else{int prefixEnd = locationPattern.indexOf(":") + 1;
if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {return findPathMatchingResources(locationPattern);
}else{returnnew Resource[] {getResourceLoader().getResource(locationPattern)};
}}} |
==>PathMatchingResourcePatternResolver.findPathMatchingResources(String locationPattern);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| protected Resource[] findPathMatchingResources(String locationPattern) throws IOException {
String rootDirPath = determineRootDir(locationPattern);
String subPattern = locationPattern.substring(rootDirPath.length());
Resource[] rootDirResources = getResources(rootDirPath);
Set result = CollectionFactory.createLinkedSetIfPossible(16);
for (int i = 0; i < rootDirResources.length; i++) {
Resource rootDirResource = rootDirResources[i];
if (isJarResource(rootDirResource)) {
result.addAll(doFindPathMatchingJarResources(rootDirResource, subPattern));
}else{
result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));
}}if (logger.isDebugEnabled()) {
logger.debug("Resolved location pattern [" + locationPattern + "] to resources " + result);
}return (Resource[]) result.toArray(new Resource[result.size()]);
} |
前面说到有一个刷新WebApplicationContext的操作,但是XmlWebApplicationContext 并没有实现refresh方法,而方法的实现写在
AbstractRefreshableWebApplicationContext 中
==>AbstractRefreshableWebApplicationContext.refresh();
1 2 3 4 5 6 7
| publicvoid refresh() throws BeansException {if (ObjectUtils.isEmpty(getConfigLocations())) {
setConfigLocations(getDefaultConfigLocations());
}
super.refresh();
} |
==>AbstractApplicationContext.refresh();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| publicvoid refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {
this.startupTime = System.currentTimeMillis();
synchronized (this.activeMonitor) {
this.active = true;
}
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this));
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
postProcessBeanFactory(beanFactory);
for (Iterator it = getBeanFactoryPostProcessors().iterator(); it.hasNext();) {
BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it.next();
factoryProcessor.postProcessBeanFactory(beanFactory);
}
if (logger.isInfoEnabled()) {if (getBeanDefinitionCount() == 0) {
logger.info("No beans defined in application context [" + getDisplayName() + "]");
}else{
logger.info(getBeanDefinitionCount() + " beans defined in application context [" +
getDisplayName() + "]");
}}
try{
invokeBeanFactoryPostProcessors();
registerBeanPostProcessors();
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
beanFactory.preInstantiateSingletons();
publishEvent(new ContextRefreshedEvent(this));
}
catch (BeansException ex) {
beanFactory.destroySingletons();
throw ex;
}}} |
posted on 2007-01-12 16:53
☜♥☞MengChuChen 阅读(2538)
评论(0) 编辑 收藏 所属分类:
Spring