Thread.currentThread()。contextClassLoader.getResource(path)似乎缓存结果。预防的?

时间:2012-08-14 22:49:40

标签: java grails groovy

我正在开发Grails 2.1应用程序,我有一个服务正在调用Thread.currentThread().contextClassLoader.getResource(fileName)来加载grails-app/conf中的配置文件(我希望这个位置无关紧要) 。

它工作正常,除了我必须重新启动grails应用程序以加载到配置文件。我真的希望每次都能读取文件内容 我要求提供资源,至少在开发过程中是这样。

另外,如果我可以避免,我想避免编写自己的缓存系统。解决方案越简单越好。

我的问题似乎与this one with velocity类似,但使用getClass().getClassLoader().getResource(path).openStream()似乎不起作用。

编辑:我想我可能遗漏了一个重要的细节。我正在检索的资源是非静态的。我正在使用grails模板引擎将值注入资源,如下所示:

Map bindings = [keys: 'values']
new SimpleTemplateEngine().createTemplate(resource).make(bindings).toString()

使用我的调试器,我发现资源文本没有变化,但了解上述内容可能会改变潜在的答案。

编辑#2:我尝试使用URLConnection.setUseCaches(false),但没有运气:

URLConnection connection = Thread.currentThread().contextClassLoader.getResource(path).openConnection()
connection.setUseCaches(false)
connection.connect()
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))
String content = reader.readLines().join('\n')
reader.close()

4 个答案:

答案 0 :(得分:3)

如果您以这种方式使用资源,可以考虑将其从grails-app / conf移至/ web-app。

当运行grails run-app时,爆炸版本的爆炸战争实际上是在一个容器中运行,其中有一些外部魔法监视各种路径以进行更改并重新编译和重新复制更新的文件,类似于手动热的方式-swap .class文件和其他资源。

对于/ web-app中的所有文件,此监控都是开箱即用的。一旦文件存在,您就可以使用ServletContext来获取相关文件的句柄。例如,您可能会执行以下操作:

def templateFile = new File(ServletContextHolder.servletContext.getRealPath('/templates/fileName.gsp')).text

并将其传递给您的模板引擎。对于锁定文件系统的环境(例如Heroku),getRealPath方法可能不起作用。或者,您也可以使用以下内容:

import org.apache.commons.io.IOUtils
def template =  IOUtils.toString(ServletContextHolder.servletContext.getResourceAsStream('/templates/fileName.gsp'), "UTF-8")

这种方法的缺点:

  • 您需要访问ServletContext,这将要求您加载容器。因此,对这段编码没有单元测试;你需要进行集成测试。
  • 在/ web-app中放置这样的资源会使它们公开。或者,如果隐私是一个问题,您可以将它们放在/ web-app / WEB-INF中。

希望这有帮助!

答案 1 :(得分:1)

你能用Spring的ResourceUtils做这个吗? http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/util/ResourceUtils.html

它看起来像ResourceUtils.getFile(“classpath:path / to / file.xyz”)

答案 2 :(得分:1)

getClass().getClassLoader().getResource(path)会返回一个网址对象,因此缓存很可能由URL / URLConnection执行。

在应用程序启动时尝试使用URLConnection.setDefaultUseCaches (false)(出于性能原因,可能仅在开发环境中)。这也可以使用setUseCaches()方法在每个URLConnection基础上设置。

答案 3 :(得分:1)

只是一个想法,但Grails服务通常是单身人士。如果您希望在每个请求上重新读取文件,您可以尝试将范围更改为原型。

相关问题