JavaEE中的配置管理

Mar*_*zer 6 java configuration properties java-ee-6 glassfish-3

我的目标

我有一个JavaEE环境(在我的特定情况下它是一个Glassfish Web配置文件),我想要一种独立于容器的方式来配置我的应用程序,具有以下功能:

  1. 没有指定其他内容时的默认配置(在WAR文件中)
  2. 自定义配置(WAR文件外)有两层:
    • 主机特定设置(在外部属性文件中;例如某些工作目录)
    • 应用程序特定设置(在数据库中;例如邮箱大小)

我希望尽可能少的前置条件(现在唯一一个是JNDI数据源)来部署和运行我的应用程序(设置JNDI数据源,部署WAR文件,在某些配置文件夹中有一个可选的.properties文件,并且 - 完成).

这引出了我的第一个问题:这是一个常见的/好的/有用的设置还是不必要的复杂和/或非常奇特?

我的想法(到目前为止)

默认配置

默认配置将位于属性文件中:

src/main/resources/config/default.properties

应用范围的描述豆读取初始化这个特性在这里:

@Named
@ApplicationScoped
public class Configuration implements Serializable {

    ...

    @PostConstruct
    public void initConfiguration() {
        loadDefaultConfiguration();
    }

    private void loadDefaultConfiguration() {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

        try (InputStream input = classLoader.getResourceAsStream("/config/default.properties")) {
            properties.load(input);
        } catch(IOException ex) {
            LOGGER.error(...);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

应用特定设置

这些设置将存储在具有键和值列的数据库表中.它们将始终通过EntityManager访问,希望JPA实现的缓存将是聪明的:).这里的优点是,在应用程序运行时可以轻松更改这些设置.

@Named
@ApplicationScoped
public class Configuration implements Serializable {

    ...

    public T getProperty(final PropertyKeyEnum key, final Class<T> type) {
        if (key.getSource() == PropertySourceEnum.DATABASE) {
            return configurationDao.getByKey(key.getKey(), type);
        }

        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

主机特定设置

最后,这是我的主要问题:

如何以独立方式访问容器中的外部属性文件?用户应该只能将myAppName.properties文件放入容器的默认配置文件夹中,应用程序应能够找到并加载该文件(至少在应用程序启动时).

我的环境

  • JavaSE 7
  • JavaEE 6
  • Glassfish 3.1.2 Web(但这不应该重要;))

更新

我在Glassfish的管理区域找到了一个位置,您可以在其中指定一些易于访问的系统属性:

System.getProperty("myApp.propertyName");
Run Code Online (Sandbox Code Playgroud)

这可以用来存储外部.properties文件的路径,但我不确定这是否干净,因为

  1. 我不知道每个容器(支持JavaEE)是否都有这么好的功能
  2. 我真的不想从Web应用程序访问普通文件

Mar*_*zer 1

在与我的同事交谈和一些研究之后,我针对主机特定(外部)配置实现了以下内容。

由于无论如何我的应用程序都需要一个工作目录,因此我决定也使用此工作目录作为外部配置的位置。因此,我要么使用环境变量(例如MYAPP_HOME),或者如果未设置该变量,则使用用户的主文件夹(例如<user.home>/.myapp):

private Path discoverRootDirectory() {
    String myAppHome = System.getenv("MYAPP_HOME");

    if (myAppHome == null) {
        return Paths.get(System.getProperty("user.home"), ".myapp");
    } else {
        return Paths.get(myAppHome);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后属性文件将照常加载:

private void loadConfiguration() {
    properties = new Properties();
    // ...
    try (InputStream inputStream = Files.newInputStream(discoverRootDirectory())) {
        properties.load(inputStream);
    } catch (FileAccessException | IOException ex) {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)