6

我的目标

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

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

我的希望是部署和运行我的应用程序(设置 JNDI 数据源,部署 WAR 文件,在某些配置文件夹中有一个可选的 .properties 文件和 -完毕)。

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

我的想法(到目前为止)

默认配置

默认配置将在属性文件中:

src/main/resources/config/default.properties

应用程序范围的 bean 在初始化时读取此属性,如下所述

@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(...);
        }
    }

}

应用程序特定设置

这些设置将存储在具有键和值列的数据库表中。它们将始终通过 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);
        }

        ...
    }
}

主机特定设置

最后,这是我的主要问题

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

我的环境

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

更新

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

System.getProperty("myApp.propertyName");

这可用于存储外部 .properties 文件的路径,但我不确定这是否是一种干净的方式,因为

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

2 回答 2

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);
    }
}

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

private void loadConfiguration() {
    properties = new Properties();
    // ...
    try (InputStream inputStream = Files.newInputStream(discoverRootDirectory())) {
        properties.load(inputStream);
    } catch (FileAccessException | IOException ex) {
        // ...
    }
}
于 2013-02-16T13:37:50.767 回答
-1

如果您正在尝试创建一种方法来保持您的应用程序可移植,我的猜测是您正在尝试编写一个程序来处理更快速有效的手动处理(由人类而不是计算机)。每个容器(Glassfish、JBoss、WebSphere 等)并不局限于必须以与另一个容器相同的方式做事。因此,如果您追求的是可移植性,它们的配置文件可以而且通常会大不相同。最好弄清楚如何在不同的服务器上运行应用程序并保存配置文件。充其量你可以在一个地方做我们所做的事情并创建带有占位符的文件,这些文件可以与简单的属性文件一起使用,其中脚本替换每个占位符的值(例如端口号等)。您多久在不同类型的服务器之间切换一次?如果你经常说,那么你会遇到比这更多的问题。最好选择一个平台并坚持下去。这样问题少很多。

如果您在这里没有得到您喜欢的答案,请尝试服务器故障(此站点的姊妹站点)。

于 2012-10-22T01:18:58.150 回答