Spring源码情操陶冶-ContextLoaderListener

ContextLoaderListener是Spring框架中一个监听器,为Spring的应用程序上下文提供了一个ServletContextListener实现,它可以在web.xml中声明,用于在Web应用程序初始化时加载Spring上下文。本篇文章将对ContextLoaderListener进行详细介绍,包括使用方法、源码分析和示例说明。

一、ContextLoaderListener的使用方法

ContextLoaderListener提供了一个ServletContextListener的实现,它创建和销毁Spring的应用程序上下文,并将其存储在ServletContext中。要使用ContextLoaderListener,需要在web.xml中声明它:

```xml

org.springframework.web.context.ContextLoaderListener

```

在web.xml中加入上述代码后,在Web应用程序启动时,ContextLoaderListener将会创建Spring的应用程序上下文,并将其存储在ServletContext中。

Spring的应用程序上下文可以通过以下方式获取:

```java

WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);

```

此代码将返回在ServletContext中已存储的Spring的应用程序上下文。获取Spring的应用程序上下文后,就可以像在其他应用程序中一样使用它了。

二、ContextLoaderListener的源码分析

ContextLoaderListener的核心在于其实现了ServletContextListener接口,因此在Web应用程序启动和关闭时,将会调用它的contextInitialized和contextDestroyed方法。我们来看一下这两个方法的实现。

1. contextInitialized方法

在contextInitialized方法中,ContextLoaderListener首先会获取Web应用程序的ServletContext:

```java

this.context = createWebApplicationContext(servletContext);

```

然后使用createWebApplicationContext方法创建Spring的应用程序上下文。

```java

protected ApplicationContext createWebApplicationContext(ServletContext sc) {

// 查找ContextLoaderListener的contextClass参数

Class contextClass = determineContextClass(sc);

// 创建BeanWiringInfoResolver

BeanWiringInfoResolver beanWiringInfoResolver = new BeanWiringInfoResolver();

// 创建WebApplicationContext进行初始化工作

WebApplicationContext context = createWebApplicationContext(sc, beanWiringInfoResolver, contextClass);

// 将WebApplicationContext存储在ServletContext中

WebApplicationContextUtils.registerWebApplicationContext(sc, context);

// 返回创建的WebApplicationContext

return context;

}

protected WebApplicationContext createWebApplicationContext(ServletContext sc, BeanWiringInfoResolver beanWiringInfoResolver, Class contextClass) {

// 创建XmlWebApplicationContext

XmlWebApplicationContext wac = new XmlWebApplicationContext();

// 设置ServletContext

wac.setServletContext(sc);

// 设置BeanWiringInfoResolver

wac.setBeanWiringInfoResolver(beanWiringInfoResolver);

// 设置ContextConfigLocation

String configLocation = sc.getInitParameter(CONFIG_LOCATION_PARAM);

if (configLocation != null) {

wac.setConfigLocation(configLocation);

}

// 设置ApplicationContext ID

String id = sc.getServletContextName();

if (id == null) {

id = ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.identityToString(wac);

}

wac.setId(id);

// 设置ClassLoader

wac.setClassLoader(sc.getClassLoader());

// 通知ApplicationContext准备刷新

wac.refresh();

// 返回创建的WebApplicationContext

return wac;

}

```

在createWebApplicationContext方法中,ContextLoaderListener首先查找参数contextClass,如果没有指定,则使用XmlWebApplicationContext作为Spring的应用程序上下文。创建XmlWebApplicationContext后,设置ServletContext、BeanWiringInfoResolver、ConfigLocation、ID和ClassLoader,并调用refresh方法刷新应用程序上下文。

在刷新过程中,XmlWebApplicationContext会解析ConfigLocation中定义的配置文件,并根据配置文件创建BeanDefinition,然后使用BeanDefinitionRegistry注册这些BeanDefinition,并最终创建所有的Bean。

最后,ContextLoaderListener使用WebApplicationContextUtils.registerWebApplicationContext方法将创建的应用程序上下文存储在ServletContext中,以便在整个Web应用程序中可以共享使用。

2. contextDestroyed方法

在contextDestroyed方法中,ContextLoaderListener将从ServletContext中获取应用程序上下文,并调用ApplicationContext的close方法关闭应用程序上下文,以确保在Web应用程序关闭时,Spring的应用程序上下文可以正确地销毁。

```java

protected void closeWebApplicationContext(ServletContext sc) {

WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(sc);

if (wac instanceof ConfigurableApplicationContext) {

((ConfigurableApplicationContext) wac).close();

}

}

public void contextDestroyed(ServletContextEvent event) {

closeWebApplicationContext(event.getServletContext());

}

```

三、ContextLoaderListener的示例说明

下面我们来看一个使用ContextLoaderListener的示例。

假设我们有一个Web应用程序,其中包含一个名为GreetingController的Controller类,并使用Spring进行组件管理。我们使用@Component注解将GreetingController标记为Spring的组件,并使用@RequestMapping注解将其映射到URL“/greeting”。代码如下:

```java

@Component

public class GreetingController {

@RequestMapping("/greeting")

public String greeting(Model model) {

model.addAttribute("message", "Hello, World!");

return "greeting";

}

}

```

还需要将配置文件spring-servlet.xml中添加以下内容:

```xml

```

最后,在web.xml文件中加入以下代码:

```xml

org.springframework.web.context.ContextLoaderListener

spring

org.springframework.web.servlet.DispatcherServlet

contextConfigLocation

classpath:spring-servlet.xml

1

spring

/

```

这样就完成了使用ContextLoaderListener的示例。在Web应用程序启动时,ContextLoaderListener将创建Spring的应用程序上下文,并在其中完成组件管理和依赖注入。在应用程序中使用GreetingController类时,Spring将创建GreetingController实例,并将其注入到其他组件中。

总结

本篇文章详细介绍了ContextLoaderListener的使用方法、源码解析和示例说明。使用ContextLoaderListener可以方便地为Spring的Web应用程序上下文提供ServletContextListener的实现,实现了创建和销毁Spring的应用程序上下文,并将其存储在ServletContext中。使用ContextLoaderListener可以方便地使用Spring进行Web开发,提高开发效率和代码可重用性。 如果你喜欢我们三七知识分享网站的文章, 欢迎您分享或收藏知识分享网站文章 欢迎您到我们的网站逛逛喔!https://www.37seo.cn/

点赞(20) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部