Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Web应用程序的配置文件-加载一次并存储在何处?_Java_Servlets_Properties - Fatal编程技术网

Java Web应用程序的配置文件-加载一次并存储在何处?

Java Web应用程序的配置文件-加载一次并存储在何处?,java,servlets,properties,Java,Servlets,Properties,我有一组属性(配置),可以根据环境进行更改。但是,一旦部署了Web应用程序,这些值就不会改变。因此,在正常程序流程中,我想读取一个应用程序。 我知道我可能可以在服务器启动时加载这些。但是,从后端的简单java类访问这些类的最佳实践是什么?这些业务类与servlet等无关,也不依赖于webapp 所以今天我通过ServletContext加载属性。然后呢?我应该将它们保存在哪里,以便其他对象可以轻松访问,而无需再次执行fileInputStream.load 谢谢。实施一个新的解决方案 以下是一个

我有一组属性(配置),可以根据环境进行更改。但是,一旦部署了Web应用程序,这些值就不会改变。因此,在正常程序流程中,我想读取一个应用程序。 我知道我可能可以在服务器启动时加载这些。但是,从后端的简单java类访问这些类的最佳实践是什么?这些业务类与servlet等无关,也不依赖于webapp

所以今天我通过ServletContext加载属性。然后呢?我应该将它们保存在哪里,以便其他对象可以轻松访问,而无需再次执行fileInputStream.load

谢谢。

实施一个新的解决方案

以下是一个基本的启动示例:

public class Config implements ServletContextListener {
    private static final String ATTRIBUTE_NAME = "config";
    private Properties config = new Properties();

    @Override
    public void contextInitialized(ServletContextEvent event) {
        try {
            config.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties"));
        } catch (IOException e) {
            throw new SomeRuntimeException("Loading config failed", e);
        }
        event.getServletContext().setAttribute(ATTRIBUTE_NAME, this);
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        // NOOP.
    }

    public static Config getInstance(ServletContext context) {
        return (Config) context.getAttribute(ATTRIBUTE_NAME);
    }

    public String getProperty(String key) {
        return config.getProperty(key);
    }
}
您可以在
web.xml
中按如下方式注册:

<listener>
    <listener-class>com.example.Config</listener-class>
</listener>


再想想,这些属性是100%特定于业务层的,而不是webapplication本身?然后,
ServletContextListener
确实很笨拙,而且耦合太紧密。只需为业务层提供自己的
Config
类,该类从类路径加载属性并将其缓存在某个
静态
变量(
Map
maybe?)中

您应该拥有对这些属性的静态引用,并以这种方式访问它们。你最终会把它们读入记忆,并保存在那里。这样,您就不必在运行时多次访问磁盘

因此,假设您有一个类
AppProperties

public class AppProperties {
  private static Properties props;

  protected static loadProperties(File propsFile) {
    ... read from disk, and set props static member ...
  }

  public static getProperties() {
    return props;
  }
}
在初始化器servlet中,可以调用
loadProperties
从磁盘读取属性。然后,在应用程序代码中,要访问属性:

String myProp = AppProperties.getProperties().getProperty("myProp");

将配置类/属性放在jar文件中,并将该jar文件放在WEB-INF/lib中。然后,您可以通过web应用程序中需要的普通类路径资源设施访问它们。

如果您的应用程序服务器支持JNDI,您可以使用JNDI


请参见我的问题(和答案):

谢谢您的回答。正是我在做的。也许我应该说得更清楚些。我试图避免在域对象中使用ServletContext或ServletContextListener。我想将其存储在POJO中并访问它。然而,我正在努力决定是否创建一个singleton properties对象并在那里加载属性。有什么想法吗?单例是相当可观的,但是在某些类中将
属性
指定为
静态
变量也就足够了。你能解释一下为什么静态是一个糟糕的解决方案吗?我不想引入框架依赖来加载配置文件。。。主要是,我试图避免ServletContext等,因为junit测试对业务类来说是一件痛苦的事情。今天我可以非常愉快地测试它们…
static
+单元测试=aaaaaargh!!顺便说一句:加载配置文件不需要框架。就为了你已经在用的情况。除此之外,我们只需重新设计普通框架已经做过的事情
ServletContextListener
等等。我同意静态问题。但我不知道如何快速地将它插入到我可以包含的工作类型jar中。顺便说一句,我正在使用RESTEasy。除了ServletContextListener,我没有一个好的钩子。还有其他具体例子吗?你能详细说明一下吗?静态引用来自何处?是的,对不起,我本想从一开始就填写更多的答案,但我被“现实世界”中的某个东西分散了注意力:)我想这是我的ServletContextListener的组合。这似乎是目前最简单的解决方案。是的,最大的好处是业务逻辑代码只需要引用
AppProperties
类,而不需要任何JEE的东西。然后,您可以让单元测试
设置
方法初始化属性,就像ServletContextListener通常所做的那样。
String myProp = AppProperties.getProperties().getProperty("myProp");