MyException - 我的异常网
当前位置:我的异常网» Web前端 » 关于spring获取webApplication.getBean多种路径和简

关于spring获取webApplication.getBean多种路径和简单解释

www.MyException.Cn  网友分享于:2015-02-08  浏览:0次
关于spring获取webApplication.getBean多种途径和简单解释
ApplicationContext ac1 = new FileSystemXmlApplicationContext("com/spark/system/applicationContext.xml");//如果配置文件放在文件系统的目录下则优先使用该方式
//com/spark/system/applicationContext.xml等价于"file:com/spark/system/applicationContext.xml"
ac1.getBean("beanId");

//ApplicationContext ac2=new ClassPathXmlApplicationContext("com/spark/system/applicationContext.xml");//如果配置文件在类路径下则优先使用该方式
//com/spark/system/applicationContext.xml 等价于"classpath:com/spark/system/applicationContext.xml"
 ac2.getBean("beanId"); 

说明:

这种方式适用于采用Spring框架的独立应用程序,需要程序通过配置文件手工初始化Spring的情况。


	public void getBean(HttpServletRequest req,HttpSession se)
	{
//		se.getServletContext() 也可以
		WebApplicationContext wac=(WebApplicationContext)req.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
		wac.getBean("");
	}
说明:此种方式正是我们下面所提到的WebApplicationContextUtils 工具类中getWebApplicationContext(ServletContext sc) 方法的内部实现,以下方式是通过spring 提供的WebApplicationContextUtils 工具类获取WebApplicationContext


方式一:

import org.springframework.web.context.support.WebApplicationContextUtils;
ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc)
ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc)
ac1.getBean("beanId");
ac2.getBean("beanId"); 
说明:
这种方式适合于采用Spring框架的B/S系统,通过ServletContext对象获取ApplicationContext对象,然后在通过它获取需要的类实例。
上面两个工具方式的区别是,前者在获取失败时抛出异常,后者返回null。


方式二:

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationObjectSupport;

public class ApplicationContextUtils extends WebApplicationObjectSupport{

	public  WebApplicationContext isgetWebApplicationContext(){
		return super.getWebApplicationContext();
	}
	
}


继承自抽象类WebApplicationObjectSupport
说明:
抽象类WebApplicationObjectSupport 继承自ApplicationObjectSupport提供getApplicationContext()方法,可以方便的获取到ApplicationContext。Spring初始化时,会通过该ApplicationObjectSupport 的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入。当然直接继承ApplicationObjectSupport自己实现也可以,既然spring 提供了更方便的抽象工具类WebApplicationObjectSupport 建议使用它。以免出现问题

下面看WebApplicationObjectSupport关键源码(红色部分)

/*** Eclipse Class Decompiler, copyright (c) 2012 cnfree (cnfree2000@hotmail.com) ***/
package org.springframework.web.context.support;

import java.io.File;
import javax.servlet.ServletContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.util.WebUtils;

public abstract class WebApplicationObjectSupport <span style="color:#FF0000;">extends ApplicationObjectSupport</span> implements ServletContextAware{

	private ServletContext servletContext;

	public final void setServletContext(ServletContext servletContext){
		if (servletContext != this.servletContext){
			this.servletContext = servletContext;
			if (servletContext != null) initServletContext(servletContext);
		}
	}

	protected boolean isContextRequired(){
		return true;
	}

	protected void initApplicationContext(ApplicationContext context){
		super.initApplicationContext(context);
		if ((this.servletContext == null)
				&& (context instanceof WebApplicationContext)){
			this.servletContext = ((WebApplicationContext)context)
					.getServletContext();
			if (this.servletContext != null)
				initServletContext(this.servletContext);
		}
	}

	protected void initServletContext(ServletContext servletContext){}

	<span style="color:#FF0000;">protected final WebApplicationContext getWebApplicationContext()
			throws IllegalStateException{
		ApplicationContext ctx = getApplicationContext();
		if (ctx instanceof WebApplicationContext){ return ((WebApplicationContext)getApplicationContext()); }
		if (isContextRequired()){ throw new IllegalStateException(
				"WebApplicationObjectSupport instance [" + this
						+ "] does not run in a WebApplicationContext but in: "
						+ ctx); }
		return null;
	}</span>

	protected final ServletContext getServletContext()
			throws IllegalStateException{
		if (this.servletContext != null){ return this.servletContext; }
		ServletContext servletContext = getWebApplicationContext()
				.getServletContext();
		if ((servletContext == null) && (isContextRequired())){ throw new IllegalStateException(
				"WebApplicationObjectSupport instance ["
						+ this
						+ "] does not run within a ServletContext. Make sure the object is fully configured!"); }
		return servletContext;
	}

	protected final File getTempDir() throws IllegalStateException{
		return WebUtils.getTempDir(getServletContext());
	}
}

下面是ApplicationObjectSupport源码

/*** Eclipse Class Decompiler, copyright (c) 2012 cnfree (cnfree2000@hotmail.com) ***/
package org.springframework.context.support;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationContextException;

public abstract class ApplicationObjectSupport implements
		ApplicationContextAware{

	protected final Log logger;

	private ApplicationContext applicationContext;

	private MessageSourceAccessor messageSourceAccessor;

	public ApplicationObjectSupport(){
		this.logger = LogFactory.getLog(super.getClass());
	}

	public final void setApplicationContext(ApplicationContext context)
			throws BeansException{
		if ((context == null) && (!(isContextRequired()))){
			this.applicationContext = null;
			this.messageSourceAccessor = null;
		}
		else if (this.applicationContext == null){
			if (!(requiredContextClass().isInstance(context))){ throw new ApplicationContextException(
					"Invalid application context: needs to be of type ["
							+ requiredContextClass().getName() + "]"); }
			this.applicationContext = context;
			this.messageSourceAccessor = new MessageSourceAccessor(context);
			initApplicationContext(context);
		}
		else if (this.applicationContext != context){ throw new ApplicationContextException(
				"Cannot reinitialize with different application context: current one is ["
						+ this.applicationContext + "], passed-in one is ["
						+ context + "]"); }
	}

	protected boolean isContextRequired(){
		return false;
	}

	protected Class requiredContextClass(){
		return ApplicationContext.class;
	}

	protected void initApplicationContext(ApplicationContext context)
			throws BeansException{
		initApplicationContext();
	}

	protected void initApplicationContext() throws BeansException{}

	public final ApplicationContext getApplicationContext()
			throws IllegalStateException{
		if ((this.applicationContext == null) && (isContextRequired())){ throw new IllegalStateException(
				"ApplicationObjectSupport instance [" + this
						+ "] does not run in an ApplicationContext"); }
		return this.applicationContext;
	}

	protected final MessageSourceAccessor getMessageSourceAccessor()
			throws IllegalStateException{
		if ((this.messageSourceAccessor == null) && (isContextRequired())){ throw new IllegalStateException(
				"ApplicationObjectSupport instance [" + this
						+ "] does not run in an ApplicationContext"); }
		return this.messageSourceAccessor;
	}
}

通过源码很容易看得出spring做的这两次封装是如何获取到WebApplicationContext的  当然自己也可以实现底层接口自己封装。

比如:继承自抽象类ApplicationObjectSupport,抽象类ApplicationObjectSupport提供getApplicationContext()方法,可以方便的获取到ApplicationContext。Spring初始化时,会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入。

再比如:实现接口ApplicationContextAware,实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 对象。Spring初始化时,会通过该方法将ApplicationContext 对象注入。

以上方法适合不同的情况,请根据具体情况选用相应的方法。
这里值得提一点的是,系统中用到上述方法的类实际上就于Spring框架紧密耦合在一起了,因为这些类是知道它们是运行在Spring框架上的,因此,系统中,应该尽量的减少这类应用,使系统尽可能的独立于当前运行环境,尽量通过DI的方式获取需要的服务提供者。


PS:除了通过applicationContext来手动获取getBean("beanId")之外,还可以通过beanfactory工厂的.getBean("beanId")获取Bean 实例

例如:

	ResourcePatternResolver resolver=new PathMatchingResourcePatternResolver();
		Resource resource=resolver.getResource("classpath:com/**/beans.xml");
		BeanFactory bf=new XmlBeanFactory(resource);
		bf.getBean("beanId");

有待研究 通过BeanFactory.getBean和ApplicationContext.getBean 的异同解释,和利弊以及使用情况。志同道合的同志可随时留言讨论,小弟欢迎大家一起学习

本文属于原创,请勿抄袭,谢谢!


文章评论

代码女神横空出世
代码女神横空出世
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
10个调试和排错的小建议
10个调试和排错的小建议
旅行,写作,编程
旅行,写作,编程
总结2014中国互联网十大段子
总结2014中国互联网十大段子
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
老程序员的下场
老程序员的下场
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
那些争议最大的编程观点
那些争议最大的编程观点
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
我是如何打败拖延症的
我是如何打败拖延症的
程序员必看的十大电影
程序员必看的十大电影
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
如何成为一名黑客
如何成为一名黑客
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
程序员都该阅读的书
程序员都该阅读的书
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
漫画:程序员的工作
漫画:程序员的工作
为什么程序员都是夜猫子
为什么程序员都是夜猫子
编程语言是女人
编程语言是女人
程序员应该关注的一些事儿
程序员应该关注的一些事儿
每天工作4小时的程序员
每天工作4小时的程序员
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
一个程序员的时间管理
一个程序员的时间管理
Java程序员必看电影
Java程序员必看电影
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
我的丈夫是个程序员
我的丈夫是个程序员
 程序员的样子
程序员的样子
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有