前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >怎么获取Spring的ApplicationContext

怎么获取Spring的ApplicationContext

作者头像
全栈程序员站长
发布2022-07-13 18:23:27
8460
发布2022-07-13 18:23:27
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

在 WEB 开发中,可能会非常少须要显示的获得 ApplicationContext 来得到由 Spring 进行管理的某些 Bean, 今天我就遇到了,在这里和大家分享一下, WEB 开发中,怎么获取 ApplicationContext

一 要想怎么获取 ApplicationContext, 首先必须明确 Spring 内部 ApplicationContext 是如何存储的。以下我们来跟踪一下源代码

首先:从大家最熟悉的地方開始

Java代码

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

上面这一段,大家非常熟悉吧。好,让我们看一看它究竟实现了些啥。

Java代码

  1. public class ContextLoaderListener<span style=“color: #ff0000;”> <span style=“color: #000000;”>implements ServletContextListener</span></span> {
  2. private ContextLoader contextLoader;
  3. /**
  4. * Initialize the root web application context.
  5. */
  6. public void <span style=“color: #000000;”>contextInitialized</span>(ServletContextEvent event) {
  7. this.contextLoader = createContextLoader();
  8. this.contextLoader.<span style=“color: #000000;”>initWebApplicationContext</span>(event.getServletContext());
  9. }//以下的略

显然,ContextLoaderListener实现了ServeletContextListenet,在ServletContext初始化的时候,会进行Spring的初始化,大家肯定会想,Spring的初始化应该与ServletContext有一定关系吧?有关系吗?接下来让我们进入

ContextLoader.initWebApplicationContext方法

Java代码

  1. public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
  2. throws IllegalStateException, BeansException {
  3. //从ServletContext中查找,是否存在以<span style=”color: #000000;”>WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE为Key的值</span>

Java代码

  1. if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null){
  2. throw new IllegalStateException(
  3. “Cannot initialize context because there is already a root application context present – “ +
  4. “check whether you have multiple ContextLoader* definitions in your web.xml!”);
  5. }
  6. try {
  7. // Determine parent for root web application context, if any.
  8. ApplicationContext parent = loadParentContext(servletContext);
  9. // it is available on ServletContext shutdown.
  10. this.context = createWebApplicationContext(servletContext, parent);
  11. //将ApplicationContext放入ServletContext中,其key为<span style=”color: #000000;”>WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE</span>

Java代码

  1. servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
  2. //将ApplicationContext放入ContextLoader的全局静态常量Map中,当中key为:<span style=”color: #000000;”>Thread.currentThread().getContextClassLoader()即当前线程类载入器</span>

Java代码

  1. currentContextPerThread.put(Thread.currentThread().getContextClassLoader(), this.context);
  2. return this.context;
  3. }

从上面的代码大家应该明确了Spring初始化之后,将ApplicationContext存到在了两个地方,那么是不是意味着我们能够通过两种方式取得ApplicationContext?

第一种获取方式:

注意:WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + “.ROOT”;

即为 “org.springframework.web.context.WebApplicationContext.ROOT”

那么咱们是不是能够这样获得ApplicationContext:

Java代码

  1. request.getSession().getServletContext().getAttribute(“org.springframework.web.context.WebApplicationContext.ROOT”)

确实能够,并且我们想到这样的方法的时候,Spring早就提供给我们接口了:

Java代码

  1. public abstract class WebApplicationContextUtils {
  2. public static WebApplicationContext getRequiredWebApplicationContext(ServletContext sc)
  3. throws IllegalStateException {
  4. WebApplicationContext wac = getWebApplicationContext(sc);
  5. if (wac == null) {
  6. throw new IllegalStateException(“No WebApplicationContext found: no ContextLoaderListener registered?”);
  7. }
  8. return wac;
  9. }

getWebApplicationContext方法例如以下:

Java代码

  1. public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
  2. return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
  3. }

哈哈,明确了吧,它和我们自己实现的方法是一样的。

这样的方法一般用在你自定义了一个Listener而且实现了ServletContextListener接口,在web.xml中你须要把这个Listener配置好

代码语言:javascript
复制
	<!--
		用于做初始化工作的监听器,一定要配置到Spring的ContextLoaderListener之后,由于要用到Spring的容器对象
	-->

	<listener>
	  <listener-class>cn.itcast.oa.Utils.InitListener</listener-class>
	</listener>

实现这个监听器的类例如以下:

代码语言:javascript
复制
public class InitListener implements ServletContextListener {

//启动时,为最大的作用于初始化
	public void contextInitialized(ServletContextEvent sce) {
		// 获取容器与相关的Service对象
		ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
		PrivilegeService privilegeService = (PrivilegeService) ac.getBean("privilegeServiceImpl");

		// 准备数据:topPrivilegeList
		List<Privilege> topPrivilegeList = privilegeService.findTopList();
		sce.getServletContext().setAttribute("topPrivilegeList", topPrivilegeList);
		System.out.println("------------> 已准备数据 <------------");
	}

	public void contextDestroyed(ServletContextEvent arg0) {

	}
}

另一种简单的

代码: ApplicationContext ac = new FileSystemXmlApplicationContext(“applicationContext.xml”); ac.getBean(“beanId”); 说明:这样的方式适用于採用Spring框架的独立应用程序,须要程序通过配置文件手工初始化Spring的情况。

然后。。。。。获取的这个ApplicationContext对象后你就能够getBean()了。。。。。啦啦

參考 http://www.blogjava.net/Todd/archive/2010/04/22/295112.html

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/118141.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年12月,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档