情景:
今天想把一个web应用中的上传路劲更改一下
于是就在配置文件作了如下变动:
<bean id="uploadServelt" class="com.xxxx.servlet.UploadServlet" scope="request" autowire="byType"> <property name="savePath" ><value>"C:\Users\admin\Desktop\upload"</value></property> </bean>
然后savePath这个变量仍然没有生效
然后就想,会不会是没有关联到配置文件
ApplicaitonContext的几种生成方法
一、ClassPathXmlApplicationContext
这种方式是通过类名路径去找到配置文件,所以配置文件只能放在项目内部
二、FileSystemXmlApplicationContext
这个跟java.io.File差不多,所以配置文件可以放在项目外部
三、WebApplicationContextUtils
有两种方法去得到ApplicationContext
- getRequiredWebApplicationContext(ServletContext)
- getWebApplicationContext(ServletContext)
推荐第一种方法,因为第一种方法当获取失败的时候会抛出异常,第二种只会返回null
原因
重点来了!!为什么第三种方法会有可能获取失败呢??
注意,这两种方法的参数都是ServletContext,所以推测,ApplicationContext是放在ServletContext里面
查一查源码
String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT"; public static WebApplicationContext getWebApplicationContext(ServletContext sc) { return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); } public static WebApplicationContext getWebApplicationContext(ServletContext sc, String attrName) { Assert.notNull(sc, "ServletContext must not be null"); Object attr = sc.getAttribute(attrName); if (attr == null) { return null; } if (attr instanceof RuntimeException) { throw (RuntimeException) attr; } if (attr instanceof Error) { throw (Error) attr; } if (attr instanceof Exception) { throw new IllegalStateException((Exception) attr); } if (!(attr instanceof WebApplicationContext)) { throw new IllegalStateException("Context attribute is not of type WebApplicationContext: " + attr); } return (WebApplicationContext) attr; }从源码看,ApplicationContext果然是放在ServletContext里面的,所以在获取之前,如果ServletContext里面没有ApplicationContext,那么就会抛出异常
ApplicationContext储存在ServletContext的默认属性名是"org.springframework.web.context.WebApplicationContext.ROOT"
然而,平时的惯性思维都以为,这种获取ApplicaitonContext的方法是spring自动完成的,不需要我们new
解决方案
先在ApplicationListener初始化的时候,用方法一或者方法二创建一个ApplicaitonContext,然后set到ServletContext里面去,然后之后就可以用第三种方法获取了,注意set的时候的属性名称,可以自定义也可以用默认的"org.springframework.web.context.WebApplicationContext.ROOT"
如果是自定义的话,就要用这个方法去获取ApplicationContext了
WebApplicationContext.getWebApplicationContext(ServletContext sc, String attrName)更正
之前说的有点不对 如果是web应用 当spring的ContextLoaderListener启动的时候,会将WebApplicationContext放入ServletContext里面去, 所以我们就大胆的使用方法三来获取吧
查看原文:http://139.129.55.235/2016/05/30/%e8%8e%b7%e5%8f%96spring%e5%ae%b9%e5%99%a8%e8%a6%81%e5%b0%8f%e5%bf%83%e7%9a%84%e5%9d%91/