spring里头各种获取ApplicationContext的方法
为啥写这个文章呢?spring各个版本不同,以及和系统框架套在一起不同,导致获取的方式不同,网络上各种版本,太乱了,写获取方式的人都不写这个获取方式是在本地还是在WEB,在那种应用服务器下,在spring那个版本下,太过分了!
我这写一些,常见的,可能经常要用的版本;
首先了解,为什么要获取这个东西:当你想通过spring获取一个你指定的类的实例的时候,而又没有通过spring加载到当前调用的类里面,例如你在filter里面,可能要对人员角色做判定,此时还没到业务层代码,但是又要访问数据库或其他的服务类。
然后再确保一点:这个context是一个全局变量,spring加载的时候,根handle信息就被装载,无论是本地应用程序还是web应用都是这样,下面分别说下如果是本地程序和其他情况的获取方式。
如果是main方法,你要启动spring,有很多方法,有基于annotation的注解来讲配置文件装载起来,当然,你想获取applicationCntext可在main方法中这样获取:
- XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));//这样来加载配置文件
还有没有其他的方式呢?有的
- ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"a.xml", "b.xml"});
还有没有其他的?有
- XmlWebApplicationContext context = new XmlWebApplicationContext();
- context.setConfigLocations(new String[] {"aaa.xml" , "bb.xml"});
- MockServletContext msc = new MockServletContext();
- context.setServletContext(msc);
- context.refresh();
- msc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);
其实方法差不多,他们有着继承关系,所以方法很多,你每次new的时候,相当于重新创建一个applicationContext,他会重新装载,所以不适合反复调用,如果自己new,你就应当把它放到一个全局变量中,用main启动的,当然你通过直接或间接的static应用到这个application即可。
而在WEB上呢,有一种是通过spring来加载spring本身的方式是:
通过实现接口:
- org.springframework.context.ApplicationContextAware
然后spring反射,来源文章:http://blog.163.com/xuyang1974@126/blog/static/2684016320101028101923914/
这种方式适在spring 2、3当中均有效:
编写类:
- import org.springframework.beans.BeansException;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.ApplicationContextAware;
- import org.springframework.stereotype.Service;
- @Service
- public class SpringContextHolder implements ApplicationContextAware {
- private static ApplicationContext applicationContext;
- @Override
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- SpringContextHolder.applicationContext = applicationContext;
- }
- public static ApplicationContext getApplicationContext() {
- return applicationContext;
- }
- public static Object getBean(String beanName) {
- return applicationContext.getBean(beanName);
- }
- public static <T>T getBean(String beanName , Class<T>clazz) {
- return applicationContext.getBean(beanName , clazz);
- }
- }
我这里是通过annotation注解的,如果不是annotation,那么可以通过配置文件:
- <bean class="xxx.xxx.xxx.SpringContextHolder"></bean>
来进行注入操作,结果一样,如果的spring配置中,没有设置byName的话,bean的配置里面记得要加参数来设置applicationContext来反射进去。
而你要加载spring,很多时候,并不是进入业务层的,因为反射是反射到业务层的,你还没有进入业务层,怎么来获取这个反射的东西呢?除非你反射的时候,用static变量来获取,那么就没有问题了;所以上面的例子中他也用的是static;
当你不想用static来反射,而经常想要用到它的时候,就有很多种获取方式了。
在spring 3以前的版本,我们在WEB应用中通常是这样获取的:
- WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(context);
而contexnt是什么呢?如果是servlet中,是可以直接通过getServletContext()获取,
而通过request要这样获取:
对于所有的tomcat通用的写法是:
- ServletContext context = req.getSession().getServletContext();
对于tomcat 7以上的写法是(也就是tomcat 7可以直接从request中获取servletContext,tomcat6不行,必须通过session才可以):
- 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();
跟踪方法明显看到内部获取增加了一个参数:
- WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(getServletContext(),attrName);
这个参数是什么呢?
经过跟踪可以发现是:
- FrameworkServlet.SERVLET_CONTEXT_PREFIX + getServletName()
而SERVLET_CONTEXT_PREFIX的定义是:
- public static final String SERVLET_CONTEXT_PREFIX = FrameworkServlet.class.getName() + ".CONTEXT.";
也就是:
- “org.springframework.web.servlet.FrameworkServlet.CONTEXT.”
而getServletName()呢?他是当前请求的servlet,可以获取到的一个web.xml里面配置的名称,例如,
如果你的web.xml中配置的是:
- <servlet>
- <servlet-name>spring</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
说明getServletName()的结果就是spring,否则就是其他,那么如果是spring,就是:
- org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring
ok,如果按照上面的配置,获取方式就是:
- request.getSession().getServletContext().getAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring");
tomcat 7以上可以写成:
- request.getServletContext().getAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring");
更为好的写法是:
- request.getSession().getServletContext().getAttribute(FrameworkServlet.SERVLET_CONTEXT_PREFIX +"spring");
以下为spring为了方便,做的一些扩展:
spring为了业务代码中获取这个参数方便,在进入业务代码前做了一个操作,在DispatcherServlet的方法:doService中doDispatch调用之前:
- request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
也就是,当你进入Controller以后,获取就不用那么麻烦了,你只需要这样就能获取到:
- request.getAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE);
当然,你可以将值写进去,看定义是:
- public static final String WEB_APPLICATION_CONTEXT_ATTRIBUTE = DispatcherServlet.class.getName() + ".CONTEXT";
那么值就应该是:
- org.springframework.web.servlet.DispatcherServlet.CONTEXT
所以在Controller中你还可以这样来获取:
- request.getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT")
经过spring包装后,你也可以通过:
- RequestContextUtils.getWebApplicationContext(request , context)
来获取,源码如下:
其实它获取的方式和上面给的方法是一样的,RequestContextUtils.getWebApplicationContext在spring 3当中,如果没有启动ContextLoaderListener(当然你可以配置监听),是不会成功的。
ContextLoaderListener的简单配置为(web.xml中):
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener>
spring 3以后基本不这样配置了。
from: http://blog.csdn.net/xieyuooo/article/details/8473503
spring里头各种获取ApplicationContext的方法相关推荐
- Spring boot Freemarker 获取ContextPath的方法
Spring boot Freemarker 获取ContextPath的两种方法: 1.自定义viewResolver,Spring boot中有一个viewResolver,这个和配置文件中的师徒 ...
- Spring MVC中获取Request的方法及分析
一.概述 在使用Spring MVC开发Web系统时,经常需要在处理请求时使用request对象,比如获取客户端IP地址.请求的URL.header中的属性(如cookie.授权信息).body中的数 ...
- 转:Spring Boot 获取 HttpServletRequest 的方法
转自: Spring Boot 获取 HttpServletRequest 的方法 - 简书本文介绍 Spring Boot 2 获取 HttpServletRequest 的方法. 目录 概述 方法 ...
- Spring获取ApplicationContext方式,和读取配置文件获取bean的几种方式
Spring获取ApplicationContext方式 我自己常用的方法: 读取一个文件1 //创建Spring容器 2 ApplicationContext ctx = new ClassPath ...
- Java普通类获取Spring框架Bean 的五种方法
方法一:在初始化时保存ApplicationContext对象 代码: ApplicationContext ac = new FileSystemXmlApplicationContex(" ...
- Spring源码之getBean(获取 bean)方法(二)解读
目录 前言 `spring` 初始化 `bean` 过程 进入类 `ClassPathXmlApplicationContext` 的构造器 `AbstractApplicationContext` ...
- spring mvc在Controller中获取ApplicationContext
spring mvc在Controller中获取ApplicationContext web.xml中进行正常的beans.xml和spring-mvc.xml的配置: 需要在beans.xml中进行 ...
- spring aop获取目标对象的方法对象(包括方法上的注解)(转)
这两天在学习权限控制模块.以前看过传智播客黎活明老师的巴巴运动网视频教程,里面就讲到权限控制的解决方案,当时也只是看看视频,没有动手实践,虽说看过几遍,可是对于系统中的权限控制还是很迷茫,所以借着这次 ...
- Spring源码解析-applicationContext.xml加载和bean的注册
applicationContext文件加载和bean注册流程 Spring对于从事Java开发的boy来说,再熟悉不过了,对于我们这个牛逼的框架的介绍就不在这里复述了,Spring这个大杂烩,怎 ...
最新文章
- 15 三明治集成方法和混合策略集成方法
- python输出特别的矩阵
- 只需三分钟!教会你如何选购及维护UPS蓄电池?
- python算法攻略_算法基础及python实现笔记一(堆和DFS)
- 单变量线性回归模型_了解如何为单变量模型选择效果最好的线性回归
- 机器学习回归算法—岭回归及案例分析
- jq阻止事件冒泡(点击子级不触发父级)的两种方法
- Android图形---Graphics(概要)
- android通过拼音搜索中文的功能
- 【云大会】之五《第七届云计算大会 Day1感受:喧嚣退潮、人气萎缩》
- 【一键激活win8.1系统】
- linux查询打印机ip,Linux C打印IP地址信息
- 看完这篇文章APP关键词覆盖增加70000|互联网行业公会
- webrtc入门:1.使用getUserMedia获取摄像头流
- VUE实现DIV点击换色
- 迅雷2014C++研发笔试卷C
- 服务器系统迁移工具,Win2008 R2迁移实战之迁移工具使用
- Windows Phone 7.5及诺基亚Lumia 800使用感受
- 一招解决win11系统字体模糊发虚不清楚的问题
- Java使用策略模式替换掉 if else
热门文章
- Android混淆详解
- 微软 CTO 韦青:对微软这样已经走过44年的公司,现在也只是个小小小的开始!!!
- 用Kubernetes部署超级账本Fabric的区块链即服务(1)
- 某银行信用卡中心——大数据反欺诈应用案例 2017-06-23 10:54 本篇案例为数据猿推出的大型“金融大数据主题策划”活动(查看详情)第一部分的系列案例/征文;感谢 百融金服 的投递 作为整体
- 郑风田:老美哪些地儿值得咱们?
- SpringBoot - 子模块下spring-boot-configuration-processor不生效问题
- 深入理解分布式技术 - 降级和熔断
- Spring Session - 使用Spring Session从零到一构建分布式session
- 江西省普通高中学业水平考试计算机,2020江西省普通高中学业水平考试缴费平台...
- IntelliJ IDEA版本和junit版本不适配