第一范文网 - 专业文章范例文档资料分享平台

Spring 源代码解析 - 入门

来源:用户分享 时间:2025/5/30 17:45:53 本文由loading 分享 下载这篇文档手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:xxxxxxx或QQ:xxxxxx 处理(尽可能给您提供完整文档),感谢您的支持与谅解。

用程序就是一个建立这个上下文体系的过程。Spring为web应用提供了上下文的扩展接口 WebApplicationContext:

Java代码 1. 2. 3. 4. 5. 6. 7.

public interface WebApplicationContext extends ApplicationContext { //这里定义的常量用于在ServletContext中存取根上下文

String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + \; ……

//对WebApplicationContext来说,需要得到Web容器的ServletContext ServletContext getServletContext(); }

而一般的启动过程,Spring会使用一个默认的实现,XmlWebApplicationContext – 这个上下文实现作为在web容器中的根上下文容器被建立起来,具体的建立过程在下面我们会详细分析。

Java代码 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.

21.

}

public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {

/** 这是和web部署相关的位置信息,用来作为默认的根上下文bean定义信息的存放位置*/ public static final String DEFAULT_CONFIG_LOCATION = \xml\;

public static final String DEFAULT_CONFIG_LOCATION_PREFIX = \; public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = \;

//我们又看到了熟悉的loadBeanDefinition,就像我们前面对IOC容器的分析中一样,这个加载工程在容器的refresh()的时候启动。

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {

//对于XmlWebApplicationContext,当然使用的是XmlBeanDefinitionReader来对bean定义信息来进行解析

XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

beanDefinitionReader.setResourceLoader(this);

beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

initBeanDefinitionReader(beanDefinitionReader); loadBeanDefinitions(beanDefinitionReader); }

protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {

22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40.

//使用XmlBeanDefinitionReader来读入bean定义信息

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {

String[] configLocations = getConfigLocations(); if (configLocations != null) {

for (int i = 0; i < configLocations.length; i++) { reader.loadBeanDefinitions(configLocations[i]); } } }

//这里取得bean定义信息位置,默认的地方是/WEB-INF/applicationContext.xml protected String[] getDefaultConfigLocations() { if (getNamespace() != null) {

return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX}; } else {

return new String[] {DEFAULT_CONFIG_LOCATION}; } } }

对于一个Spring激活的web应用程序,可以通过使用Spring代码声明式的指定在web应用程序启动时载入应用程序上下文(WebApplicationContext),Spring的ContextLoader是提供这样性能的类,我们可以使用 ContextLoaderServlet或者ContextLoaderListener的启动时载入的Servlet来实例化Spring IOC容器 – 为什么会有两个不同的类来装载它呢,这是因为它们的使用需要区别不同的Servlet容器支持的Serlvet版本。但不管是 ContextLoaderSevlet还是 ContextLoaderListener都使用ContextLoader来完成实际的WebApplicationContext的初始化工作。这个ContextLoder就像是Spring Web应用程序在Web容器中的加载器booter。当然这些Servlet的具体使用我们都要借助web容器中的部署描述符来进行相关的定义。 下面我们使用ContextLoaderListener作为载入器作一个详细的分析,这个Servlet的监听器是根上下文被载入的地方,也是整个 Spring web应用加载上下文的第一个地方;从加载过程我们可以看到,首先从Servlet事件中得到ServletContext,然后可以读到配置好的在web.xml的中的各个属性值,然后ContextLoder实例化WebApplicationContext并完成其载入和初始化作为根上下文。当这个根上下文被载入后,它被绑定到web应用程序的ServletContext上。任何需要访问该ApplicationContext的应用程序代码都可以从WebApplicationContextUtils类的静态方法来得到:

Java代码 1.

WebApplicationContext getWebApplicationContext(ServletContext sc)

以Tomcat作为Servlet容器为例,下面是具体的步骤:

1.Tomcat 启动时需要从web.xml中读取启动参数,在web.xml中我们需要对ContextLoaderListener进行配置,对于在web应用启动入口是在ContextLoaderListener中的初始化部分;从Spring MVC上看,实际上在web容器中维护了一系列的IOC容器,其中在ContextLoader中载入的IOC容器作为根上下文而存在于 ServletContext中。

Java代码

1. 2. 3. 4. 5. 6. 7.

//这里对根上下文进行初始化。

public void contextInitialized(ServletContextEvent event) { //这里创建需要的ContextLoader

this.contextLoader = createContextLoader();

//这里使用ContextLoader对根上下文进行载入和初始化

this.contextLoader.initWebApplicationContext(event.getServletContext()); }

通过ContextLoader建立起根上下文的过程,我们可以在ContextLoader中看到: Java代码 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24.

public WebApplicationContext initWebApplicationContext(ServletContext servletContext) throws IllegalStateException, BeansException {

//这里先看看是不是已经在ServletContext中存在上下文,如果有说明前面已经被载入过,或者是配置文件有错误。

if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) { //直接抛出异常 ……… }

…………… try {

// 这里载入根上下文的父上下文

ApplicationContext parent = loadParentContext(servletContext);

//这里创建根上下文作为整个应用的上下文同时把它存到ServletContext中去,注意这里使用的ServletContext的属性值是

//ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,以后的应用都是根据这个属性值来取得根上下文的 - 往往作为自己上下文的父上下文

this.context = createWebApplicationContext(servletContext, parent); servletContext.setAttribute(

WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); ……….

return this.context; }

………… }

建立根上下文的父上下文使用的是下面的代码,取决于在web.xml中定义的参数:locatorFactorySelector,这是一个可选参数:

Java代码 1.

protected ApplicationContext loadParentContext(ServletContext servletContext)

2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.

throws BeansException {

ApplicationContext parentContext = null;

String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM);

String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM);

if (locatorFactorySelector != null) {

BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector); ……..

//得到根上下文的父上下文的引用

this.parentContextRef = locator.useBeanFactory(parentContextKey); //这里建立得到根上下文的父上下文

parentContext = (ApplicationContext) this.parentContextRef.getFactory(); }

return parentContext; }

得到根上下文的父上下文以后,就是根上下文的创建过程:

Java代码 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.

protected WebApplicationContext createWebApplicationContext(

ServletContext servletContext, ApplicationContext parent) throws BeansException { //这里需要确定我们载入的根WebApplication的类型,由在web.xml中配置的contextClass中配置的参数可以决定我们需要载入什么样的ApplicationContext, //如果没有使用默认的。

Class contextClass = determineContextClass(servletContext); ………

//这里就是上下文的创建过程

ConfigurableWebApplicationContext wac =

(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); //这里保持对父上下文和ServletContext的引用到根上下文中 wac.setParent(parent);

wac.setServletContext(servletContext);

//这里从web.xml中取得相关的初始化参数

String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM); if (configLocation != null) {

wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation, ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS)); }

搜索更多关于: Spring 源代码解析 - 入门 的文档
Spring 源代码解析 - 入门.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.diyifanwen.net/c9608c59e54862m61dlh2_4.html(转载请注明文章来源)
热门推荐
Copyright © 2012-2023 第一范文网 版权所有 免责声明 | 联系我们
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:xxxxxx 邮箱:xxxxxx@qq.com
渝ICP备2023013149号
Top