2015-10-15 55 views
0

在我们的Grails Web应用程序中,我们希望使用外部配置文件,以便我们可以在不发布新版本的情况下更改配置。我们还希望这些文件位于应用程序目录之外,以便在持续集成期间保持不变。在首次运行Grails Web应用程序时复制默认外部配置

我们需要做的最后一件事是确保存在外部配置文件。如果他们不这样做,那么我们希望创建它们,用预定义内容(生产环境默认值)填充它们,然后像​​以前一样使用它们。这允许任何管理员在不详细了解实际可用选项的情况下更改应用程序的设置。

为此,有一对夫妇的文件内web-app/WEB-INF/conf准备在应用程序的第一次运行复制到外部配置位置。

到目前为止这么好。但是,我们需要在应用程序初始化之前这样做,以便对与数据源定义相关的生产相关修改进行考虑。

我可以在Config.groovy文件中执行copy-and-load操作,但我不知道目前WEB-INF/conf目录的绝对位置。

在初始化的早期阶段,我该如何获取位置?还有其他解决方案吗?

回答

0

我终于通过使用Java的定位放置在类路径的资源能力,这一解决自己。

我以后将.groovy文件复制到外面,将它们放入grails-app/conf目录(它位于类路径上),并在其名称后附加后缀,以便在打包应用程序时不会进行编译。因此,现在我有包含配置默认值(适用于所有环境)的*Config.groovy文件和包含生产环境默认值(覆盖预编译的默认值)的文件*Config.groovy.production

现在 - Config.groovy开始是这样的:

grails.config.defaults.locations = [ EmailConfig, AccessConfig, LogConfig, SecurityConfig ] 

environments { 
    production { 
     grails.config.locations = ConfigUtils.getExternalConfigFiles(
      '.production', 
      "${userHome}${File.separator}.config${File.separator}${appName}", 
      'AccessConfig.groovy', 
      'Config.groovy', 
      'DataSource.groovy', 
      'EmailConfig.groovy', 
      'LogConfig.groovy', 
      'SecurityConfig.groovy' 
     ) 
    } 
} 

然后ConfigUtils类:

public class ConfigUtils { 

    // Log4j may not be initialized yet 
    private static final Logger LOG = Logger.getGlobal() 

    public static def getExternalConfigFiles(final String defaultSuffix, final String externalConfigFilesLocation, final String... externalConfigFiles) { 

     final def externalConfigFilesDir = new File(externalConfigFilesLocation) 

     LOG.info "Loading configuration from ${externalConfigFilesDir}" 

     if (!externalConfigFilesDir.exists()) { 
      LOG.warning "${externalConfigFilesDir} not found. Creating..." 
      try { 
       externalConfigFilesDir.mkdirs() 
      } catch (e) { 
       LOG.severe "Failed to create external configuration storage. Default configuration will be used." 
       e.printStackTrace() 
       return [] 
      } 
     } 

     final def cl = ConfigUtils.class.getClassLoader() 
     def result = [] 

     externalConfigFiles.each { 

      final def file = new File(externalConfigFilesDir, it) 
      if (file.exists()) { 
       result << file.toURI().toURL() 
       return 
      } 

      final def error = false 
      final def defaultFileURL = cl.getResource(it + defaultSuffix) 
      final def defaultFile 

      if (defaultFileURL) { 
       defaultFile = new File(defaultFileURL.toURI()) 
       error = !defaultFile.exists(); 
      } else { 
       error = true 
      } 

      if (error) { 
       LOG.severe "Neither of ${file} or ${defaultFile} exists. Skipping..." 
       return 
      } 

      LOG.warning "${file} does not exist. Copying ${defaultFile} -> ${file}..." 

      try { 
       FileUtils.copyFile(defaultFile, file) 
      } catch (e) { 
       LOG.severe "Couldn't copy ${defaultFile} -> ${file}. Skipping..." 
       e.printStackTrace() 
       return 
      } 

      result << file.toURI().toURL() 
     } 

     return result 
    } 

} 
0

这是最佳做法。

通常,不要写入部署应用程序的文件夹。你无法控制它。下一次推出将删除您在那里编写的所有内容。

相反,利用内置的配置功能,真正亲的使用(春季和/或JPA)。

JNDI是仰视如数据库,文件和URL资源的规范。

操作将不得不配置JNDI,但他们很感激关注。

他们还需要一组初始的配置文件,并准备根据需要由开发团队做出的时代变迁。

一如既往,所有的配置文件都应该在你的源代码仓库中。

相关问题