一.使用ApplicationContext获得Bean
首先新建一个类,该类必须实现ApplicationContextAware接口,改接口有一个方法,public void setApplicationContext(ApplicationContext applicationContext)throws BeansException,也就是说框架会自动调用这个方法返回一个ApplicationContext对象。具体类如下:
package com.bijian.study.test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class SpringContextUtils implements ApplicationContextAware {// Spring的工具类,用来获得配置文件中的bean
private static ApplicationContext applicationContext = null;
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
SpringContextUtils.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
public static Object getBean(String name, Class requiredType)
throws BeansException {
return applicationContext.getBean(name, requiredType);
}
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
public static boolean isSingleton(String name)
throws NoSuchBeanDefinitionException {
return applicationContext.isSingleton(name);
}
public static Class getType(String name)
throws NoSuchBeanDefinitionException {
return applicationContext.getType(name);
}
public static String[] getAliases(String name)
throws NoSuchBeanDefinitionException {
return applicationContext.getAliases(name);
}
}
该类中有一个getBean(String name)方法,该方法用applicationContext去获得Bean实例,而applicationContext是由系统启动时自动设置的。
注意,需要把该类在applicationContext.xml配置文件中进行注册。<bean id="springUtil" class="com.bijian.study.test.SpringContextUtils "/>
二.通过BeanFactory接口获得Bean
也是新建一个类,不过该类需要实现BeanFactoryAware接口,该接口有一个方法public void setBeanFactory(BeanFactory beanFactory) throws BeansException;该方法是为了设置BeanFactory对象,系统会在启动的时候自动设置BeanFactory。具体代码如下:
package com.bijian.study.test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
public class SpringBeanFactoryUtils implements BeanFactoryAware {
private static BeanFactory beanFactory = null;
private static SpringBeanFactoryUtils factoryUtils = null;
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
SpringBeanFactoryUtils.beanFactory = beanFactory;
}
public static BeanFactory getBeanFactory() {
return beanFactory;
}
public static SpringBeanFactoryUtils getInstance() {
if (factoryUtils == null) {
// factoryUtils =
// (SpringBeanFactoryUtils)beanFactory.getBean("springBeanFactoryUtils");
factoryUtils = new SpringBeanFactoryUtils();
}
return factoryUtils;
}
public static Object getBean(String name) {
return beanFactory.getBean(name);
}
}
不过应该注意的是,改类中有一个getInstance方法,由于该代码是网上摘抄的,他提供了这么一个方法,目的是利用单例模式获得该类的一个实例,但由于getBean(String name)方法是静态的,所以用不用单例都无关紧要,经过测试,两种方法都行的通。
另外一点就是必须把该类添加到applicationContext.xml的配置文件中<bean id="springBeanFactoryUtils" class="com.bijian.study.test.SpringBeanFactoryUtils"/>
三.在servlet中可以用WebApplicationContext类去获取Bean,具体做法是:
ServletContext context = request.getServletContext();
//ServletContext context = request.getSession().getServletContext();
WebApplicationContext webcontext = (WebApplicationContext)context.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
helloService = (HelloService) webcontext.getBean("helloService");
logger.info(helloService.processService("WebApplicationContext test"));
其中context是servlet的上下文,在servlet中可以通过this.getServletContext()或者request.getSession().getServletContext();获得servletContext。但是一点,spring的配置文件必须在WEB-INF下。WebApplicationContext 有一个方法getBean(String name);其实WebApplicationContext 就是ApplicationContext的另一种形式而已。
另外,在普通的java类中,即不是在servlet中可以用ContextLoader获得。ContextLoader是org.springframework.web.context包当中的一个类。
WebApplicationContext webApplication = ContextLoader.getCurrentWebApplicationContext();
helloService = (HelloService) webApplication.getBean("helloService");
logger.info(helloService.processService("ContextLoader.getCurrentWebApplicationContext() test"));
用这种方法就能获取一个WebApplicationContext 的对象。
最后经过测试,在重复100000次的基础上,第一二中方法只用了16毫秒,而第三种方法消耗了62毫秒,所以推荐使用第一二种方法。
四.非WEB项目
即在java main函数中执行spring的代码,如下有四种方式。
package com.bijian.study.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import com.bijian.study.service.HelloService;
public class Main {
public static void main(String[] args) throws Exception {
String[] path1 = {"WebContent/WEB-INF/springMVC-servlet.xml"};
ApplicationContext context1 = new FileSystemXmlApplicationContext(path1);
HelloService helloService1 = context1.getBean(HelloService.class);
System.out.println(helloService1.processService("bijian"));
String path2="WebContent/WEB-INF/springMVC-servlet.xml";
ApplicationContext context2 = new FileSystemXmlApplicationContext(path2);
HelloService helloService2 = context2.getBean(HelloService.class);
System.out.println(helloService2.processService("bijian"));
ApplicationContext context = new FileSystemXmlApplicationContext("/WebContent/WEB-INF/springMVC-servlet.xml");
//HelloService helloService = context.getBean(HelloService.class);
HelloService helloService = (HelloService) context.getBean("helloService");
System.out.println(helloService.processService("bijian"));
GenericXmlApplicationContext context4 = new GenericXmlApplicationContext();
context4.setValidating(false);
context4.load("classpath:springMVC-servlet.xml");
context4.refresh();
HelloService helloService4 = context4.getBean(HelloService.class);
System.out.println(helloService4.processService("bijian"));
}
}
特别说明:context4.load("classpath:springMVC-servlet.xml");方式,需将springMVC-servlet.xml拷贝一份到src目录下,否则执行会报“class path resource [springMVC-servlet.xml] cannot be opened because it does not exist”,如下所示。
附:Web工程中验证的代码
@RequestMapping("/greeting")
public ModelAndView greeting(@RequestParam(value = "name", defaultValue = "World") String name, HttpServletRequest request) {
Map<String, Object> map = new HashMap<String, Object>();
try {
//由于浏览器会把中文直接换成ISO-8859-1编码格式,如果用户在地址打入中文,需要进行如下转换处理
String tempName = new String(name.getBytes("ISO-8859-1"), "utf-8");
logger.trace("tempName:" + tempName);
logger.info(tempName);
String userName = helloService.processService(tempName);
map.put("userName", userName);
logger.trace("运行结果:" + map);
helloService = (HelloService) SpringContextUtils.getBean("helloService");
logger.info(helloService.processService("SpringContextUtils test"));
helloService = (HelloService) SpringBeanFactoryUtils.getBean("helloService");
logger.info(helloService.processService("SpringBeanFactoryUtils test"));
ServletContext context = request.getServletContext();
//ServletContext context = request.getSession().getServletContext();
WebApplicationContext webcontext = (WebApplicationContext)context.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
helloService = (HelloService) webcontext.getBean("helloService");
logger.info(helloService.processService("WebApplicationContext test"));
WebApplicationContext webApplication = ContextLoader.getCurrentWebApplicationContext();
helloService = (HelloService) webApplication.getBean("helloService");
logger.info(helloService.processService("ContextLoader.getCurrentWebApplicationContext() test"));
} catch (UnsupportedEncodingException e) {
logger.error("HelloController greeting方法发生UnsupportedEncodingException异常:" + e);
} catch (Exception e) {
logger.error("HelloController greeting方法发生Exception异常:" + e);
}
return new ModelAndView("/hello", map);
}
工程完整代码见附件《SpringMVC.zip》。