Spring MVC Web应用上下文

     Spring MVC是建立在Spring IoC容器的基础上,然而Spring IoC是一个独立的模块,因此并不能直接在Web环境中发挥作用。为了在Web环境中使用Ioc,就需要Spring提供一个适合于Web环境的相关容器(WebApplicationContext),以及基于此容器的IoC启动过程,将IoC导入,这个启动过程应该与Web容器启动过程相集成。下面着重介绍Web应用上下文。
WebApplicationContext 类继承体系   :

      可以看到,Web应用上下文的实现是基于基本Ioc容器ApplicatoionContext相关接口,并在此基础上加入了适用于Web环境的相关功能扩展。
1) WebApplicationContext接口实现
public interface WebApplicationContext extends ApplicationContext {

String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
String SCOPE_REQUEST = "request";
String SCOPE_SESSION = "session";
      ...
      ...
ServletContext getServletContext();

}
在该接口中,定义了几个常量,比如 ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,这个常量用于索引在ServletContext中保存的根Web应用上下文。还有就是 ServletContext  getServletContext () 方法,通过这个方法可以得到当前web容器的Servlet上下文。
2) ConfigurableWebApplicationContext 实现
 public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext {
String APPLICATION_CONTEXT_ID_PREFIX = WebApplicationContext.class.getName() + ":";
String SERVLET_CONFIG_BEAN_NAME = "servletConfig";
//设置与该WebApplicationContext相关的ServletContext 
void setServletContext(ServletContext servletContext);
//设置与该WebApplicationContext相关的Servlet的servletConfig
void setServletConfig(ServletConfig servletConfig);
ServletConfig getServletConfig();
//设置该WebApplicationContext依赖的bean定义资源配置路径
void setConfigLocation(String configLocation);

void setConfigLocations(String... configLocations);

String[] getConfigLocations();

}
   ConfigurableWebApplicationContext继承自WebApplicationContext接口,并且提供了设置 ServletContext 以及上下文配置资源路径的相关函数。
3) AbstractRefreshableWebApplicationContext 类
public abstract class AbstractRefreshableWebApplicationContext extends AbstractRefreshableConfigApplicationContext
implements ConfigurableWebApplicationContext, ThemeSource {

/** Servlet context that this context runs in */
private ServletContext servletContext;

/** Servlet config that this context runs in, if any */
private ServletConfig servletConfig;

/** Namespace of this context, or {@code null} if root */
private String namespace;

/** the ThemeSource for this ApplicationContext */
private ThemeSource themeSource;


   public AbstractRefreshableWebApplicationContext() {
      setDisplayName("Root WebApplicationContext");
}


@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}

@Override
public ServletContext getServletContext() {
return this.servletContext;
}

@Override
public void setServletConfig(ServletConfig servletConfig) {
this.servletConfig = servletConfig;
      if (servletConfig != null && this.servletContext == null) {
         setServletContext(servletConfig.getServletContext());
}
   }

@Override
public ServletConfig getServletConfig() {
return this.servletConfig;
}

@Override
public void setNamespace(String namespace) {
this.namespace = namespace;
      if (namespace != null) {
         setDisplayName("WebApplicationContext for namespace '" + namespace + "'");
}
   }

@Override
public String getNamespace() {
return this.namespace;
}

@Override
public String[] getConfigLocations() {
return super.getConfigLocations();
}

@Override
public String getApplicationName() {
return (this.servletContext != null ? this.servletContext.getContextPath() : "");
}

/**
    * Create and return a new {@link StandardServletEnvironment}. Subclasses may override
    * in order to configure the environment or specialize the environment type returned.
    */
@Override
protected ConfigurableEnvironment createEnvironment() {
return new StandardServletEnvironment();
}

/**
    * Register request/session scopes, a {@link ServletContextAwareProcessor}, etc.
    */
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
      beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}

/**
    * This implementation supports file paths beneath the root of the ServletContext.
    * @see ServletContextResource
    */
@Override
protected Resource getResourceByPath(String path) {
return new ServletContextResource(this.servletContext, path);
}

/**
    * This implementation supports pattern matching in unexpanded WARs too.
    * @see ServletContextResourcePatternResolver
    */
@Override
protected ResourcePatternResolver getResourcePatternResolver() {
return new ServletContextResourcePatternResolver(this);
}

/**
    * Initialize the theme capability.
    */
@Override
protected void onRefresh() {
this.themeSource = UiApplicationContextUtils.initThemeSource(this);
}

/**
    * {@inheritDoc}
    * <p>Replace {@code Servlet}-related property sources.
    */
@Override
protected void initPropertySources() {
      ConfigurableEnvironment env = getEnvironment();
      if (env instanceof ConfigurableWebEnvironment) {
         ((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, this.servletConfig);
}
   }

@Override
public Theme getTheme(String themeName) {
return this.themeSource.getTheme(themeName);
}

}

4)Spring MVC使用的WebApplicationContext实现
   Spring MVC使用一个默认的WebApplicationContext来 作为Ioc容器,这个Ioc容器就是XmlWebApplicationContext。通过类继承体系可以看到其实现继承于 AbstractRefreshableWebApplicationContext抽象类,而AbstractRefreshableWebApplicationContext又继承自 AbstractRefreshableConfigApplicationContext。

  
  
public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {

  //设置的默认的BeanDefinition的地方,在/WEB-INF/applicationContext.xml文件中
public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
  //默认的bean配置文件目录前缀和文件后缀
public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";
public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";

  //loadBeanDefinitions函数,在Ioc容器启动时,通过该函数加载、注册BeanDefinition
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
     //用XmlBeanDefinitionReader 类来对BeanDefinition信息进行解析
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEnvironment(getEnvironment());
    //设置ResourceLoader资源导入器,因ApplicationContext是DefaultResource子类,因此这里传入this,使用该DefaultResourceLoader来定位BeanDefinition资源文件
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
initBeanDefinitionReader(beanDefinitionReader);
    //通过定义好的XmlBeanDefinitionReader 来载入BeanDefinition。
loadBeanDefinitions(beanDefinitionReader);
}

protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
   }
//对多个BeanDefinition定义文件,通过XmlBeanDefinitionReader 逐个载入
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
      String[] configLocations = getConfigLocations();
      if (configLocations != null) {
for (String configLocation : configLocations) {
            reader.loadBeanDefinitions(configLocation);
}
      }
   }
 //获取默认资源位置,默认的位置是/WEB-INF/applicationContext.xml
@Override
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};
}
   }

}

   XmlWebApplicationContext中基本的上下文功能都通过类继承来获得,需要处理的就是获取Bean定义信息。这里是获取web容器环境指定的资源如/WEB-INF/applicationContext.xml。在获取到bean定义后,就如同Spring基本Ioc上下文容器ApplicationContext一样通过XmlBeanDefinitionReader来载入bean定义信息,最终完成上下文初始化。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值