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