Web应用在Spring管理的Bean类里得到上下文信息:路径等
前两天工作中遇到一个问题,运行的web应用依赖了一个使用native code的jar包,在编译打包的时候,所有的jar包和依赖的native code都被打包到WEB-INF/lib/文件夹下。这时候就遇到了一个问题,大家都知道java的web应用中, WEB-INF/这个文件夹是受保护的,这里受保护的含义就是,你不能在代码通过相对路径来访问WEB-INF/文件夹下面的资源,即下面的代码会报FileNotFoundException:
objectA.load("/WEB-INF/**/*")
//或
objectA.load("WEB-INF/**/*")
那么这时候要如何才能读到WEB-INF下面的资源呢?刚才始的时候,想到了两种比较低级的方法来解决这个问题:1. 将所以需要的资源文件放到resin/lib/文件夹下面, 这时候就可以通过相对路径lib/need_source/来直接访问资源了,当然这样所带来的问题也是显而易见的,就是应用的侵入性,所有运行此web应用的服务上都必须被放入所需的资源文件,其丑陋性可想而知。2. 换了一个方式思想,但是还没有脱离丑陋的本质,就是加一个build.properties文件,这个文件里指定应用被unwar以后,WEB-INF/lib/目前的绝对路径,然后在ant war打包的时候,就可以通过filter来设置这个值,但是这样所带来的不便也是很明显的。就是为这两个问题烦恼的时候,终于找到了最终的解决方案:问题简单化:实际上我们的需求是获取spring开发的web项目在服务器上的绝对路径。而我们已经知道servletContext有一个servletContext.getRealPath("/");方法,这个方法就能获取项目的绝对路径。因此,我们的问题就变成如何在Spring管理的POJO的bean中得到servletContext这个对象。 这个一个很悖论的问题,因为Spring管理的BEAN是POJO的,根本见不着servletconfig和servletcontext的影子。
这里我需要指出spring给我们提供了两个接口:org.springframework.web.context.ServletContextAware和
org.springframework.web.context.ServletConfigAware。我们可以让我们的bean实现上边的任何一个接口就能获取到servletContext了 .
public class DicBean implements ServletContextAware{
private ServletContext servletContext;
public void setServletContext(ServletContext sc) {
this.servletContext=sc;
System.out.println("项目的绝对路径为:"+servletContext.getRealPath("/"));
}
}
这样,我们的bean就能够直接获取到servletContext了。
如果你想要servletConfig,那方法一样,只是实现的接口不同了。
原理推想:应该是在创建spring的sessionFactory的时候,将应用服务器的相关属性一并加载,查看创建的bean是否实现相关接口,如果实现了,就将相关值赋予bean。
注意点:
1、这东西是无法用junit进行单元测试的,因为他依赖于应用服务器
spring有几个这样的XXXAware接口,当然按这样方法处理之后就违反了Spring一直坚持的非入侵性,但是这时候这样很好的解决问题了,那么就OK了,有得必有失嘛!