为啥写这个文章呢?spring各个版本不同,以及和系统框架套在一起不同,导致获取的方式不同,网络上各种版本,太乱了,写获取方式的人都不写这个获取方式是在本地还是在web,在那种应用服务器下,在spring那个版本下,太过分了!
我这写一些,常见的,可能经常要用的版本;
首先了解,为什么要获取这个东西:当你想通过spring获取一个你指定的类的实例的时候,而又没有通过spring加载到当前调用的类里面,例如你在filter里面,可能要对人员角色做判定,此时还没到业务层代码,但是又要访问数据库或其他的服务类。
然后再确保一点:这个context是一个全局变量,spring加载的时候,根handle信息就被装载,无论是本地应用程序还是web应用都是这样,下面分别说下如果是本地程序和其他情况的获取方式。
如果是main方法,你要启动spring,有很多方法,有基于annotation的注解来讲配置文件装载起来,当然,你想获取applicationcntext可在main方法中这样获取:
还有没有其他的方式呢?有的
其实从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();
跟踪方法明显看到内部获取增加了一个参数:
这个参数是什么呢?
经过跟踪可以发现是:
而servlet_context_prefix的定义是:
也就是:
而getservletname()呢?他是当前请求的servlet,可以获取到的一个web.xml里面配置的名称,例如,
如果你的web.xml中配置的是:
说明getservletname()的结果就是spring,否则就是其他,那么如果是spring,就是:
ok,如果按照上面的配置,获取方式就是:
tomcat 7以上可以写成:
更为好的写法是:
以下为spring为了方便,做的一些扩展:
spring为了业务代码中获取这个参数方便,在进入业务代码前做了一个操作,在dispatcherservlet的方法:doservice中dodispatch调用之前:
也就是,当你进入controller以后,获取就不用那么麻烦了,你只需要这样就能获取到:
当然,你可以将值写进去,看定义是:
那么值就应该是:
所以在controller中你还可以这样来获取:
经过spring包装后,你也可以通过:
来获取,源码如下:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiInBnaukTO2czXzIjNyYDN3UzMx8CX2AzLcFDMzEDMy8CXzRWYvxGc19CX0Vmbu4GZzNmL51mLn1Wavw1LcpDc0RHaiojIsJye.jpg)
其实它获取的方式和上面给的方法是一样的,requestcontextutils.getwebapplicationcontext在spring 3当中,如果没有启动contextloaderlistener(当然你可以配置监听),是不会成功的。
contextloaderlistener的简单配置为(web.xml中):
spring 3以后基本不这样配置了。