在web项目中获取ApplicationContext上下文的3种主要方式及适用情况
最近在做web项目,需要写一些工具方法,涉及到通过Java代码来获取spring中配置的bean,并对该bean进行操作的情形。而最关键的一步就是获取ApplicationContext,过程中纠结和错误了很久,总结一下获取ApplicationContext的三种方式:
方式一:实现ApplicationContextAware接口
对于实现ApplicationContextAware接口的类,spring容器在初始化的时候会扫描他,并把容器的context环境注入给它。如下:
public class BeanUtil implements ApplicationContextAware { private ApplicationContext context; @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException { System.out.println("进入这个set方法..."); System.out.println("容器本身:" + (ctx==null)); this.context = ctx; }
但同时,必须在spring的配置文件中注入该类:
<bean id="sys" class="org.test.util.BeanUtil"/>
注:虽说通过这种方式可以得到spring上下文,但必须考虑到:调用该工具类的Java类也必须注册成bean,并指定一个BeanUtil类型的属性引用sys bean,而不能通过代码的方式去获取这个工具类. 这样就违背了工具类的初衷,因为我们为了使用工具类而去把一个可能并不需要注册成bean的普通java类也注册成一个bean,这显然是多此一举的。
方式二:WebApplicationContext wc = ContextLoader.getCurrentWebApplicationContext();
注:我使用这种方式去获取上下文,但一直是null,后来查阅相关API才发现,使用该种方式的Java类必须是一个servlet或者action.普通类是无法直接使用的——或者是在web容器已经开启的情况下可以通过该方法获得上下文,假设此时再通过Resources方式new,得到的上下文将不会是此时容器中的上下文,因而也无法对容器中的bean进行管理了。也就是说,你随便写一个类,在它的main方法中透过调用这个方法,是无法获取到这个类所在项目的spring上下文的!
方式三:Resource方式
即:
public class SysBeans implements { private static ApplicationContext context; public static ApplicationContext getContext() { context = new FileSystemXmlApplicationContext("WebRoot/WEB-INF/conf/applicationContext-base.xml"); // context = new FileSystemXmlApplicationContext("",""); return context; } }
注:new ClassPathXmlApplicationContext (..)的方式只能获取位于类路径下的配置,而new FileSystemXmlApplicationContext(..)则可以获取到WEB-INF下的配置。通过filesystem的方式时,建议写相对路径,即从webRoot/WEN-INF/...xml开始写。当这两种resource方式需要同时加载多个配置时,参数可以用逗号(,)隔开,或者传入一个string[]类型的路径数组。