天天看点

spring里头各种获取ApplicationContext的方法

为啥写这个文章呢?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包装后,你也可以通过:

来获取,源码如下:

spring里头各种获取ApplicationContext的方法

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

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

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