获取spring容器上下文(webApplicationContext)的几种方法
在很多情况,我们需要先获取spring容器上下文,即webApplicationContext,然后通过webApplicationContext来获取其中的bean。典型的情况是,我想在一个并未委托给spring容器管理的对象里,去引用一个spring容器管理的对象,此时,@Resource注解是无法发挥作用的。此时必须使用webApplicationContext.getBean("beanName")才能从容器中取到这个java对象,不然我们就只能自己去new了。
方法1::ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
经验证是可行的,但是有个问题,就是执行这句代码的时候很耗时。本人猜测这句代码会重新new一个容器对象,相当于重新载入了一次applicationContext.xml里面配置的类,重新去create一个ApplicationContext,而不是去拿在项目启动之初生成的那个ApplicationContext。
方法2.首先建立一个工具类
package com.wonyen.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class MySpringContext implements ApplicationContextAware {
private static ApplicationContext context;//声明一个静态变量用于保存spring容器上下文
@Override
public void setApplicationContext(ApplicationContext context)
throws BeansException {
this.context=context;
}
public static ApplicationContext getContext(){
return context;
}
}
1.可见该工具类实现了ApplicationContextAware接口,实现该接口的类会接收到spring容器传过来的ApplicationContext对象,从而可以实现操纵spring容器中的所有bean的效果。但是这里我们并不在这个工具类里面去获取bean,我们暂且把获取来的ApplicationContext对象存放起来,放在哪里呢,就是放在该类的一个静态变量中context中,然后我们再给它一个静态的get方法,供其他的类去调用。
2.有了这个工具类还没用,spring容器不会无缘无故去执行setApplicationContext方法把ApplicationContext 对象传入给它,所以必须在ApplicationContext.xml文件里面去配置,如下所示。
<!-- util -->
<bean class="com.wonyen.util.MySpringContext"></bean>
这样,当项目启动时,就会加载这个工具类,并把ApplicationContext 传入。当然你也可以采用注解的方式,即在该类上加上@Component注解。
3.在其他类调用,只需要这样一行代码就可以了。
ApplicationContext context =MySpringContext.getContext();
经验证,采用这种方式获取的ApplicationContext的速度明显比前面那种快很多。
方法3:还有一种方法可以获取ApplicationContext,就是传入一个ServletContext对象。然后用WebApplicationContextUtils的getWebApplicationContext获取一个WebApplicationContext,WebApplicationContext是ApplicationContext的子类,他比ApplicationContext类多了一个获取ServletContext的方法。
ServletContext servletContext = event.getServletContext();
ApplicationContext application = WebApplicationContextUtils
.getWebApplicationContext(servletContext);
其实上述方法能获取到WebApplicationContext时因为web项目在启动的时候,在启动spring容器的时候,把WebApplicationContext作为一个属性放入了ServletContext中,所以我们才可以采用spring提供的这个方法来获取到WebApplicationContext。
方法4:因为WebApplicationContext是ApplicationContext的子类,所以获取到WebApplicationContext其实就是获取到了ApplicationContext。所以还有一种更为简单的方法,直接通过ContextLoader的静态方法getCurrentWebApplicationContext()就可以获取到当前的WebApplicationContext对象.
代码如下:
WebApplicationContext webApplicationContext = ContextLoader
.getCurrentWebApplicationContext();
PSSS:关于第一种方法和后面三种方法,为了验证猜想,即采用new ClassPathXmlApplicationContext("applicationContext.xml");这种方法会重新生成一个ApplicationContext对象,做了如下代码的验证。
ApplicationContext context = MySpringContext.getContext();
ApplicationContext newContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
System.out.println("获取已有的ApplicationContext对象" + context);
System.out.println("新建的ApplicationContext" + newContext);
得到的结果是:
可见这两个确实不是同一个对象。验证成功。