JavaEE中的配置管理

时间:2012-10-21 08:10:48

标签: java configuration properties java-ee-6 glassfish-3

我的目标

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

  1. 未指定任何其他内容时的默认配置(在WAR文件中)
  2. 自定义配置(WAR文件外)分为两层:
    • 主机特定设置(在外部属性文件中;例如某些工作目录)
    • 应用程序特定设置(在数据库中;例如邮箱大小)
  3. 我的愿望是,尽可能少的前置条件(现在唯一一个是JNDI数据源)来部署和运行我的应用程序(设置JNDI数据源,部署WAR文件,在某些配置中有一个可选的.properties文件文件夹和 - 完成)。

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

    我的想法(到目前为止)

    默认配置

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

    src/main/resources/config/default.properties

    应用程序作用域bean在初始化时读取此属性,如here所述:

    @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应用程序普通文件访问

2 个答案:

答案 0 :(得分: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) {
        // ...
    }
}

答案 1 :(得分:-1)

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

如果你没有得到你喜欢的答案,请试试Server Fault(这个姐妹网站)。