为啥写这个文章呢?spring各个版本不同,以及和系统框架套在一起不同,导致获取的方式不同,网络上各种版本,太乱了,写获取方式的人都不写这个获取方式是在本地还是在WEB,在那种应用服务器下,在spring那个版本下,太过分了!

我这写一些,常见的,可能经常要用的版本;

首先了解,为什么要获取这个东西:当你想通过spring获取一个你指定的类的实例的时候,而又没有通过spring加载到当前调用的类里面,例如你在filter里面,可能要对人员角色做判定,此时还没到业务层代码,但是又要访问数据库或其他的服务类。

然后再确保一点:这个context是一个全局变量,spring加载的时候,根handle信息就被装载,无论是本地应用程序还是web应用都是这样,下面分别说下如果是本地程序和其他情况的获取方式。

如果是main方法,你要启动spring,有很多方法,有基于annotation的注解来讲配置文件装载起来,当然,你想获取applicationCntext可在main方法中这样获取:

[java] view plaincopy
  1. XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));//这样来加载配置文件

还有没有其他的方式呢?有的

[java] view plaincopy
  1. ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"a.xml", "b.xml"});
还有没有其他的?有
[java] view plaincopy
  1. XmlWebApplicationContext context = new XmlWebApplicationContext();
  2. context.setConfigLocations(new String[] {"aaa.xml" , "bb.xml"});
  3. MockServletContext msc = new MockServletContext();
  4. context.setServletContext(msc);
  5. context.refresh();
  6. msc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);

其实方法差不多,他们有着继承关系,所以方法很多,你每次new的时候,相当于重新创建一个applicationContext,他会重新装载,所以不适合反复调用,如果自己new,你就应当把它放到一个全局变量中,用main启动的,当然你通过直接或间接的static应用到这个application即可。
而在WEB上呢,有一种是通过spring来加载spring本身的方式是:
通过实现接口:
[java] view plaincopy
  1. org.springframework.context.ApplicationContextAware
然后spring反射,来源文章:http://blog.163.com/xuyang1974@126/blog/static/2684016320101028101923914/
这种方式适在spring 2、3当中均有效:
编写类:
[java] view plaincopy
  1. import org.springframework.beans.BeansException;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.ApplicationContextAware;
  4. import org.springframework.stereotype.Service;
  5. @Service
  6. public class SpringContextHolder implements ApplicationContextAware {
  7. private static ApplicationContext applicationContext;
  8. @Override
  9. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  10. SpringContextHolder.applicationContext = applicationContext;
  11. }
  12. public static ApplicationContext getApplicationContext() {
  13. return applicationContext;
  14. }
  15. public static Object getBean(String beanName) {
  16. return applicationContext.getBean(beanName);
  17. }
  18. public static <T>T getBean(String beanName , Class<T>clazz) {
  19. return applicationContext.getBean(beanName , clazz);
  20. }
  21. }
我这里是通过annotation注解的,如果不是annotation,那么可以通过配置文件:
[html] view plaincopy
  1. <bean class="xxx.xxx.xxx.SpringContextHolder"></bean>
来进行注入操作,结果一样,如果的spring配置中,没有设置byName的话,bean的配置里面记得要加参数来设置applicationContext来反射进去。
而你要加载spring,很多时候,并不是进入业务层的,因为反射是反射到业务层的,你还没有进入业务层,怎么来获取这个反射的东西呢?除非你反射的时候,用static变量来获取,那么就没有问题了;所以上面的例子中他也用的是static;

当你不想用static来反射,而经常想要用到它的时候,就有很多种获取方式了。
spring 3以前的版本,我们在WEB应用中通常是这样获取的:
[java] view plaincopy
  1. WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(context);
而contexnt是什么呢?如果是servlet中,是可以直接通过getServletContext()获取,
而通过request要这样获取:
对于所有的tomcat通用的写法是:
[java] view plaincopy
  1. ServletContext context = req.getSession().getServletContext();
对于tomcat 7以上的写法是(也就是tomcat 7可以直接从request中获取servletContext,tomcat6不行,必须通过session才可以):
[java] view plaincopy
  1. ServletContext context = req.getServletContext();

其实从spring 3过后,获取的方法就有所改变,变得很诡异,因为竟然不兼容以前的获取方法,spring 3当中将其进行了进一步的包装,你在其他地方可能看到各种各样的版本。

spring 2中之所以可以那样获取,是因为spring 2当中通常会配置一个listener,由他来加载spring,他在filter之前;spring 3当中,通过org.springframework.web.servlet.DispatcherServlet来装载spring的信息,初始化在其父亲类:org.springframework.web.servlet.FrameworkServlet中方法:initWebApplicationContext();

跟踪方法明显看到内部获取增加了一个参数:

[java] view plaincopy
  1. WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(getServletContext(),attrName);

这个参数是什么呢?

经过跟踪可以发现是:

[java] view plaincopy
  1. FrameworkServlet.SERVLET_CONTEXT_PREFIX + getServletName()

而SERVLET_CONTEXT_PREFIX的定义是:

[java] view plaincopy
  1. public static final String SERVLET_CONTEXT_PREFIX = FrameworkServlet.class.getName() + ".CONTEXT.";

也就是:

[java] view plaincopy
  1. “org.springframework.web.servlet.FrameworkServlet.CONTEXT.”

而getServletName()呢?他是当前请求的servlet,可以获取到的一个web.xml里面配置的名称,例如,

如果你的web.xml中配置的是:

[html] view plaincopy
  1. <servlet>
  2. <servlet-name>spring</servlet-name>
  3. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  4. <load-on-startup>1</load-on-startup>
  5. </servlet>

说明getServletName()的结果就是spring,否则就是其他,那么如果是spring,就是:

[java] view plaincopy
  1. org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring

ok,如果按照上面的配置,获取方式就是:

[java] view plaincopy
  1. request.getSession().getServletContext().getAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring");

tomcat 7以上可以写成:

[java] view plaincopy
  1. request.getServletContext().getAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring");

更为好的写法是:

[html] view plaincopy
  1. request.getSession().getServletContext().getAttribute(FrameworkServlet.SERVLET_CONTEXT_PREFIX +"spring");

以下为spring为了方便,做的一些扩展:

spring为了业务代码中获取这个参数方便,在进入业务代码前做了一个操作,在DispatcherServlet的方法:doService中doDispatch调用之前:

[java] view plaincopy
  1. request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());


也就是,当你进入Controller以后,获取就不用那么麻烦了,你只需要这样就能获取到:

[java] view plaincopy
  1. request.getAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE);

当然,你可以将值写进去,看定义是:

[java] view plaincopy
  1. public static final String WEB_APPLICATION_CONTEXT_ATTRIBUTE = DispatcherServlet.class.getName() + ".CONTEXT";

那么值就应该是:

[java] view plaincopy
  1. org.springframework.web.servlet.DispatcherServlet.CONTEXT

所以在Controller中你还可以这样来获取:

[java] view plaincopy
  1. request.getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT")

经过spring包装后,你也可以通过:

[java] view plaincopy
  1. RequestContextUtils.getWebApplicationContext(request , context)

来获取,源码如下:

其实它获取的方式和上面给的方法是一样的,RequestContextUtils.getWebApplicationContext在spring 3当中,如果没有启动ContextLoaderListener(当然你可以配置监听),是不会成功的。

ContextLoaderListener的简单配置为(web.xml中):

[html] view plaincopy
  1. <listener>
  2. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  3. </listener>

spring 3以后基本不这样配置了。

from: http://blog.csdn.net/xieyuooo/article/details/8473503

spring里头各种获取ApplicationContext的方法相关推荐

  1. Spring boot Freemarker 获取ContextPath的方法

    Spring boot Freemarker 获取ContextPath的两种方法: 1.自定义viewResolver,Spring boot中有一个viewResolver,这个和配置文件中的师徒 ...

  2. Spring MVC中获取Request的方法及分析

    一.概述 在使用Spring MVC开发Web系统时,经常需要在处理请求时使用request对象,比如获取客户端IP地址.请求的URL.header中的属性(如cookie.授权信息).body中的数 ...

  3. 转:Spring Boot 获取 HttpServletRequest 的方法

    转自: Spring Boot 获取 HttpServletRequest 的方法 - 简书本文介绍 Spring Boot 2 获取 HttpServletRequest 的方法. 目录 概述 方法 ...

  4. Spring获取ApplicationContext方式,和读取配置文件获取bean的几种方式

    Spring获取ApplicationContext方式 我自己常用的方法: 读取一个文件1 //创建Spring容器 2 ApplicationContext ctx = new ClassPath ...

  5. Java普通类获取Spring框架Bean 的五种方法

    方法一:在初始化时保存ApplicationContext对象 代码: ApplicationContext ac = new FileSystemXmlApplicationContex(" ...

  6. Spring源码之getBean(获取 bean)方法(二)解读

    目录 前言 `spring` 初始化 `bean` 过程 进入类 `ClassPathXmlApplicationContext` 的构造器 `AbstractApplicationContext` ...

  7. spring mvc在Controller中获取ApplicationContext

    spring mvc在Controller中获取ApplicationContext web.xml中进行正常的beans.xml和spring-mvc.xml的配置: 需要在beans.xml中进行 ...

  8. spring aop获取目标对象的方法对象(包括方法上的注解)(转)

    这两天在学习权限控制模块.以前看过传智播客黎活明老师的巴巴运动网视频教程,里面就讲到权限控制的解决方案,当时也只是看看视频,没有动手实践,虽说看过几遍,可是对于系统中的权限控制还是很迷茫,所以借着这次 ...

  9. Spring源码解析-applicationContext.xml加载和bean的注册

    applicationContext文件加载和bean注册流程 ​ Spring对于从事Java开发的boy来说,再熟悉不过了,对于我们这个牛逼的框架的介绍就不在这里复述了,Spring这个大杂烩,怎 ...

最新文章

  1. 15 三明治集成方法和混合策略集成方法
  2. python输出特别的矩阵
  3. 只需三分钟!教会你如何选购及维护UPS蓄电池?
  4. python算法攻略_算法基础及python实现笔记一(堆和DFS)
  5. 单变量线性回归模型_了解如何为单变量模型选择效果最好的线性回归
  6. 机器学习回归算法—岭回归及案例分析
  7. jq阻止事件冒泡(点击子级不触发父级)的两种方法
  8. Android图形---Graphics(概要)
  9. android通过拼音搜索中文的功能
  10. 【云大会】之五《第七届云计算大会 Day1感受:喧嚣退潮、人气萎缩》
  11. 【一键激活win8.1系统】
  12. linux查询打印机ip,Linux C打印IP地址信息
  13. 看完这篇文章APP关键词覆盖增加70000|互联网行业公会
  14. webrtc入门:1.使用getUserMedia获取摄像头流
  15. VUE实现DIV点击换色
  16. 迅雷2014C++研发笔试卷C
  17. 服务器系统迁移工具,Win2008 R2迁移实战之迁移工具使用
  18. Windows Phone 7.5及诺基亚Lumia 800使用感受
  19. 一招解决win11系统字体模糊发虚不清楚的问题
  20. Java使用策略模式替换掉 if else

热门文章

  1. Android混淆详解
  2. 微软 CTO 韦青:对微软这样已经走过44年的公司,现在也只是个小小小的开始!!!
  3. 用Kubernetes部署超级账本Fabric的区块链即服务(1)
  4. 某银行信用卡中心——大数据反欺诈应用案例 2017-06-23 10:54 本篇案例为数据猿推出的大型“金融大数据主题策划”活动(查看详情)第一部分的系列案例/征文;感谢 百融金服 的投递 作为整体
  5. 郑风田:老美哪些地儿值得咱们?
  6. SpringBoot - 子模块下spring-boot-configuration-processor不生效问题
  7. 深入理解分布式技术 - 降级和熔断
  8. Spring Session - 使用Spring Session从零到一构建分布式session
  9. 江西省普通高中学业水平考试计算机,2020江西省普通高中学业水平考试缴费平台...
  10. IntelliJ IDEA版本和junit版本不适配