Spring-WebApplicationContext解读

简介: Spring-WebApplicationContext解读

概述


WebApplicationContext是专门为web应用准备的,它允许从相对于Web根目录的路径中装载资源配置文件完成初始化工作。


从WebApplication中可以获取ServletContext的引用,整个Web应用上线文对象作为属性放在到ServletContext中,以便Web应用能访问Spring应用上下文。


Spring专门为此提供了一个工具类WebApplicationContextUtils,通过该类的getWebApplicationContext(ServletContext sc)方法,可以从ServletContext中获取WebApplicationContext实例。


Web应用环境下Bean的作用域


在非Web环境下,Bean只有single和prototype两种作用域。

WebApplicationContext为Bean添加了3个新的作用域

  • request
  • session
  • globalSession


20170714102907146.jpg


WebApplicationContext类体系结构



20170711142520309.jpg



由类继承图可以看出,WebApplicationContext扩展了ApplicationContext。

WebApplicationContext定义了一个常

ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,在上线文启动的时候。


20170714101355189.jpg

WebApplicationContext实例即以此为键放在ServletContext的属性列表中,可以通过下面的语句从Web容器中获取WebApplicationContext

WebApplicationContext wac = (WebApplicationContext)servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)

正式WebApplicationUtils工具类getWebApplicationContext(ServletContext sc)方法的内部实现。

这样Spring的Web应用上下文和Web容器的上下文应用就可以实现互访,二者实现了融合。

20170714101843453.jpg



20170711142318969.jpg


ConfigurableWebApplication


20170714102351271.jpg


ConfigurableWebApplicationContext 扩展了WebApplicaiton, 它允许通过配置的方式实例化WebApplicationContext,其中两个重要的方法:

void setServletContext(ServletContext servletContext);

为Spring设置Web应用上下文,以便二者整合。

void setConfigLocations(String... configLocations);


设置Spring配置文件地址,如/WEB-INF/smart-dao.xml ,/WEB-INF/smart-service.xml ,配置文件地址是相对于web根目录的地址。

但用户也可以使用带有资源前缀类型的地址 如 classpath:/com/smart/beans.xml


WebApplicationContext初始化


WebApplicationContext的初始化方式,不同于BeanFactory、ApplicationContext, WebApplicationContext需要ServletContext实例,也就是说必须拥有Web容器的前提下才能完成启动。


通常情况下,在web.xml中配置自启动的Servlet或者定义Web容器监听器(ServletContextListener),借助二者中的任何一个,就可以完成Spring Web应用上下文的启动工作。


注意:

所有的版本的Web容器都可以定义自启动的Servlet,但是只有Servlet2.3及以上版本的Web容器才支持Web容器监听器


Spring分别提供了用于启动WebApplicationContext的Servlet和Web容器监听器:


org.springframework.web.context.ContextLoaderServlet(spring3.0及以后版本中已删除)

org.springframework.web.context.ContextLoaderListener

3.0之后的版本只能选择ContextLoaderListener实现,并在web.xml中配置完成。


使用ContextLoaderLisetener启动WebApplicationContext

<!--(1) 从类路径下加载Spring配置文件,classpath关键字-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-context.xml</param-value>
    </context-param>
    <!--(2)负责启动Spring容器的监听器,它将引用(1)处的上下文参数获得Spring配置文件的地址 -->
    <listener>
        <listener-class>
        org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>


ContextLoaderListener通过Web容器上下文参数contextConfigLocation获取Spring配置文件的位置,可以自动多个配置文件,用逗号 空格 或者冒号分开均可。


对于未带资源类型前缀的配置文件路径,WebApplicationContext默认这些路径相对于Web的根路径部署。当然也可以采用带资源类型前缀的路径配置,如 classpath:spring-context.xml .


WebApplicationContext中的日志文件的两种配置方式


由于WebApplicationContext启动需要使用日志功能

两种配置方式:

  • 将Log4J的配置文件放在类路径class下,这时Log4J引擎可以顺利启动。
  • 放在其他位置,必须在web.xml中通过Log4jConfigListener加载
    (Log4jConfigListener在 Spring 4.2.1及以后被废弃)


20170715102726434.jpg


Apache Log4j 2 : https://logging.apache.org/log4j/2.x/


Apache Log4j 2 is an upgrade to Log4j that provides significant improvements over its predecessor, Log4j 1.x, and provides many of the improvements available in Logback while fixing some inherent problems in Logback’s architecture.

<!--(1) 从类路径下加载Spring配置文件,classpath关键字-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-context.xml</param-value>
    </context-param>
    <!-- 如果log4j并没有放到类路径的根目录下,比如放在了/WEB-INF/log4j.properties,需要在web.xml中加载 如下 -->
    <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>/WEB-INF/log4j.properties</param-value>
    </context-param>
     <listener>   
         <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> 
     </listener>
    <!--(2)负责启动Spring容器的监听器,它将引用(1)处的上下文参数获得Spring配置文件的地址 -->
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

20170715103346117.jpg


经验证,可以正确加载启动


如何在项目中使用Log4j 2

具体查看另外一篇博文 Spring-Spring Web项目中配置使用Log4j 2


使用JavaConfig(Java注解)的方式启动

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
    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_3_0.xsd"
    version="3.0">
    <display-name>Archetype Created Web Application</display-name>
    <!--通过指定context参数,让Spring使用AnnotationConfigWebApplicationContext而非XmlWebApplicationContext启动容器-->
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </context-param>
    <!--指定标注了@Configuration的配置类,多个类,使用逗号或者空格分隔-->
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>com.xgj.AppConfig1,com.xgj.AppConfig2</param-value>  
    </context-param>  
     <!-- ContextLoaderListener监听器根据上面的配置使用
     AnnotationConfigWebApplicationContext根据contextConfigLocation指定的类启动Spring容器-->
    <listener>
        <listener-class>rg.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>


使用Groovy DSL配置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">
    <!--通过指定context参数,让Spring使用GroovyWebApplicationContext而非
    XmlWebApplicationContext或AnnotationConfigWebApplicationContext启动容器 -->
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.GroovyWebApplicationContext
        </param-value>
    </context-param>
    <!-- 指定标注了Groovy的配置文件-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:conf/spring-mvc.groovy
        </param-value>
    </context-param>
    <!-- ContextLoaderListener监听器将根据上面配置使用
         AnnotationConfigWebApplicationContext根据contextConfigLocation
         指定的配置类启动Spring容器-->
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
</web-app>


spring-mvc.groovy

import org.hibernate.validator.HibernateValidator
import org.springframework.context.support.ReloadableResourceBundleMessageSource
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean
import org.springframework.web.servlet.i18n.CookieLocaleResolver
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor
import org.springframework.web.servlet.view.InternalResourceViewResolver
beans {
    xmlns context: "http://www.springframework.org/schema/context"
    xmlns mvc: "http://www.springframework.org/schema/mvc"
    context.'component-scan'('base-package': "com.smart")
    mvc.'annotation-driven'('validator': "validator")
    validator(LocalValidatorFactoryBean) {
        providerClass = HibernateValidator.class
        validationMessageSource = ref("messageSource")
    }
    messageSource(ReloadableResourceBundleMessageSource) {
        basenames = ["classpath:messages", "classpath:org/hibernate/validator/ValidationMessages"]
        defaultEncoding = "UTF-8"
        cacheSeconds = 60
    }
    viewResolver(InternalResourceViewResolver) {
        prefix = "/WEB-INF/jsp/"
        suffix = ".jsp"
    }
    mvc.interceptors() {
        localeChangeInterceptor(LocaleChangeInterceptor) {
            paramName = "language"
        }
    }
    cookieLocaleResolver(CookieLocaleResolver) {
        cookieName = "language"
        cookieMaxAge = "3600"
        defaultLocale = "zh_CN"
    }
}


相关文章
|
Java 关系型数据库 数据库
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——Spring Boot 事务配置
本文介绍了 Spring Boot 中的事务配置与使用方法。首先需要导入 MySQL 依赖,Spring Boot 会自动注入 `DataSourceTransactionManager`,无需额外配置即可通过 `@Transactional` 注解实现事务管理。接着通过创建一个用户插入功能的示例,展示了如何在 Service 层手动抛出异常以测试事务回滚机制。测试结果表明,数据库中未新增记录,证明事务已成功回滚。此过程简单高效,适合日常开发需求。
1832 0
|
应用服务中间件 nginx
Nginx rewrite(URL)地址重定向
Nginx rewrite(URL)地址重定向
1122 0
|
XML 数据格式
Camunda常用功能
Camunda常用接口简介
4698 1
Camunda常用功能
|
9月前
|
SQL Java 数据库连接
事务的七种传播行为及其应用场景
本文介绍了事务的七种传播行为及其应用场景,包括 PROPAGATION_REQUIRED、PROPAGATION_SUPPORTS、PROPAGATION_REQUIRES_NEW 等,帮助开发者理解事务管理机制。同时讲解了 Java 中 SQL 操作与对象数据不同步的问题,强调重新查询与手动管理的必要性,并说明 MyBatis 批量操作的最佳实践。
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
2756 26
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
Java Maven Spring
SpringBoot配置跨模块扫描问题解决方案
在分布式项目中,使用Maven进行多模块开发时,某些模块(如xxx-common)没有启动类。如何将这些模块中的类注册为Spring管理的Bean对象?本文通过案例分析,介绍了两种解决方案:常规方案是通过`@SpringBootApplication(scanBasePackages)`指定扫描路径;推荐方案是保持各模块包结构一致(如com.xxx),利用SpringBoot默认扫描规则自动识别其他模块中的组件,简化配置。
2092 1
SpringBoot配置跨模块扫描问题解决方案
|
消息中间件 存储 负载均衡
2024消息队列“四大天王”:Rabbit、Rocket、Kafka、Pulsar巅峰对决
本文对比了 RabbitMQ、RocketMQ、Kafka 和 Pulsar 四种消息队列系统,涵盖架构、性能、可用性和适用场景。RabbitMQ 以灵活路由和可靠性著称;RocketMQ 支持高可用和顺序消息;Kafka 专为高吞吐量和低延迟设计;Pulsar 提供多租户支持和高可扩展性。性能方面,吞吐量从高到低依次为
7133 1
|
XML 缓存 算法
SpringBoot2 | SpingBoot FilterRegistrationBean 注册组件 | FilterChain 责任链源码分析(九)
SpringBoot2 | SpingBoot FilterRegistrationBean 注册组件 | FilterChain 责任链源码分析(九)
470 0
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
监控 数据可视化 前端开发
基于python django的电商数据分析系统,包括大屏和登录
本文介绍了一个基于Python Django框架开发的电商数据分析系统,该系统具备大屏展示功能和用户登录机制,旨在帮助电商企业实时监控和分析销售数据,支持多维度数据分析和趋势预测。
573 0
基于python django的电商数据分析系统,包括大屏和登录

热门文章

最新文章