spring容器监听器

摘要:
“);}Loglogger=LogFactory.getLog;servletContext.log;如果{logger.info;}longstartTime=系统。currentTimeMillis();尝试{//创建一个上下文,稍后将对此进行详细解释。#1if{this.context=createWebApplicationContext;}如果{ConfigurationWebApplicationContextcwac=this.context;如果(!

web.xml配置文件

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
    classpath:spring/spring-*.xml
  </param-value>
</context-param>

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

ContextLoaderListener上下文加载监听器

spring容器监听器第1张

  
  /**
   * servlet容器创建时创建spring容器
   */
  @Override
public void contextInitialized(ServletContextEvent event) { initWebApplicationContext(event.getServletContext()); } /** * servlet容器销毁时注销spring容器 */ @Override public void contextDestroyed(ServletContextEvent event) { closeWebApplicationContext(event.getServletContext()); ContextCleanupListener.cleanupAttributes(event.getServletContext()); }

创建spring容器

public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
        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!");
        }

        Log logger = LogFactory.getLog(ContextLoader.class);
        servletContext.log("Initializing Spring root WebApplicationContext");
        if (logger.isInfoEnabled()) {
            logger.info("Root WebApplicationContext: initialization started");
        }
        long startTime = System.currentTimeMillis();

        try {// 创建上下文,后文详解#1
            if (this.context == null) {
                this.context = createWebApplicationContext(servletContext);
            }
            if (this.context instanceof ConfigurableWebApplicationContext) {
                ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
                if (!cwac.isActive()) {
                    if (cwac.getParent() == null) {
                        ApplicationContext parent = loadParentContext(servletContext);
                        cwac.setParent(parent);
                    }
            // 刷新上下文包括解析、注册、实例化bean等,后文详解#2 configureAndRefreshWebApplicationContext(cwac, servletContext); } }
       // 将创建好的上下文放到application作用域中 servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
this.context); ClassLoader ccl = Thread.currentThread().getContextClassLoader(); if (ccl == ContextLoader.class.getClassLoader()) { currentContext = this.context; } else if (ccl != null) { currentContextPerThread.put(ccl, 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; } }

书接前文#1

protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
     // 获得具体的上下文类即XmlWebApplicationContext
        Class<?> contextClass = determineContextClass(sc);
        if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
            throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
                    "] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
        }
     // 实例化XmlWebApplicationContext对象,构造函数反射
        return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
    }

书接前文#2

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
        if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
            String idParam = sc.getInitParameter(CONTEXT_ID_PARAM);
            if (idParam != null) {
                wac.setId(idParam);
            }
            else {
                wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
                        ObjectUtils.getDisplayString(sc.getContextPath()));
            }
        }

        wac.setServletContext(sc);
     // 获得<context-param>标签中的内容 String configLocationParam
= sc.getInitParameter(CONFIG_LOCATION_PARAM); if (configLocationParam != null) { wac.setConfigLocation(configLocationParam); }
ConfigurableEnvironment env = wac.getEnvironment(); if (env instanceof ConfigurableWebEnvironment) { ((ConfigurableWebEnvironment) env).initPropertySources(sc, null); }      // 检查有没有自定义的上下文 customizeContext(sc, wac);
     // 刷新上下文 wac.refresh(); }

接下来是销毁spring容器

public void closeWebApplicationContext(ServletContext servletContext) {
        servletContext.log("Closing Spring root WebApplicationContext");
        try {
            if (this.context instanceof ConfigurableWebApplicationContext) {
          // 这里包括广播shutdown事件,销毁bean,销毁BeanFactory等 ((ConfigurableWebApplicationContext)
this.context).close(); } } finally { ClassLoader ccl = Thread.currentThread().getContextClassLoader(); if (ccl == ContextLoader.class.getClassLoader()) { currentContext = null; } else if (ccl != null) { currentContextPerThread.remove(ccl); }
        // application作用域中去除上下文 servletContext.removeAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if (this.parentContextRef != null) { this.parentContextRef.release(); } } }
static void cleanupAttributes(ServletContext sc) {
        Enumeration<String> attrNames = sc.getAttributeNames();
        while (attrNames.hasMoreElements()) {
            String attrName = attrNames.nextElement();
            if (attrName.startsWith("org.springframework.")) {
                Object attrValue = sc.getAttribute(attrName);
          // 对于实现了DisposableBean接口的bean,容器销毁时执行destroy方法
if (attrValue instanceof DisposableBean) { try { ((DisposableBean) attrValue).destroy(); } catch (Throwable ex) { logger.error("Couldn't invoke destroy method of attribute with name '" + attrName + "'", ex); } } } } }

免责声明:文章转载自《spring容器监听器》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【转载】python接口测试实战-Fiddler、PostmanC 语言函数指针下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

阿里云PTS分享-用性能测试工具JMeter实现基于供应链业务上对于WebSocket 协议的压测

性能测试PTS(Performance Testing Service)是面向所有技术相关背景人员的云化性能测试工具,孵化自阿里内部平台。有别于传统工具的繁复,PTS以互联网化的交互,面向分布式和云化的设计,更适合当前的主流技术架构。无论是自研还是适配开源的功能,PTS都可以轻松模拟大量用户访问业务的场景,任务随时发起,免去搭建和维护成本。更是紧密结合监控...

Android Studio教程06-布局,监听器以及基本控件

目录 2. 监听器 3. 布局 3.1. 布局分类 (1). Linear Layout (2). Relative Layout (3). ListView (4). Grid View 4. 其他比较杂的内容 4.1. 距离单位的区别px,dp,sp 4.2. 控件的外边距和内边距 1. 什么是内外边距 2. 如何设置内外边距...

Android 中的监听器模式与观察者模式

1、   观察者模式与监听器机制 1.1 观察者模式 1.2 监听器(Listener)机制 代码的基本框架: * 被监控着 package com.wonders.group; import java.util.Collection;   public class ModelTie {     private Collection<Object&g...

Oracle ORA12514 监听程序当前无法识别连接描述符中请求的服务

在连接数据库的时候,有时会遇到一个“ORA12514:监听程序当前无法识别连接描述符中请求的服务”的错误,这个错误其实就是数据库动态注册(关于动态注册会在稍后讲解)不生效,导致监听器无法识别客户端连接符中提供的服务名,从而拒绝建立数据库连接时报的错误信息,所以就需要对监听器配置做修改。 在这里,还需对问题进行细化,有时候可能会发现,在刚开启监听器的时候会发...

项目中使用Quartz集群分享--转载

原文:http://hot66hot.iteye.com/blog/1726143 在公司分享了Quartz,发布出来,希望大家讨论补充. CRM使用Quartz集群分享 一:CRM对定时任务的依赖与问题 二:什么是quartz,如何使用,集群,优化 三:CRM中quartz与Spring结合使用 1:CRM对定时任务的依赖与问题 1)依赖 (1)每天晚上...

Android网络通信(8):WiFi Direct

Android网络通信之WiFi Direct 使用Wi-Fi Direct技术可以让具备硬件支持的设备在没有中间接入点的情况下进行直接互联。Android 4.0(API版本14)及以后的系统都提供了对Wi-Fi Direct的API支持。通过对这些API的使用,开发者可以实现支持Wi-Fi Direct的设备间进行相互探测和连接,从而获得较之蓝牙更远距...