Java .properties文件为强类型类

时间:2009-10-16 13:25:08

标签: java properties annotations

有没有办法将属性文件作为强类型类? 我想有代码生成器,但使用注释做它会更酷。

我的意思是;

foo.properties file
keyFoo = valuefoo
keyBar = valuebar

也许是

@properties(file="foo.properties")
class foo { }

变为

class foo {
  String getKeyFoo() { }
  String getKeyBar() { }
}

如果没有,我会为此启动一个开源项目吗?

补充问题;

认为我们有一个foo.properties文件,可以说超过10个条目; 并认为它被用作一个简单的配置文件。我认为这个配置条目应作为配置类提供,并将相关的getXXX方法提供给设计的其他部分。然后系统的其余部分通过提供的类访问配置,而不是处理密钥名称,并且不需要打扰配置的来源。然后,当您测试调用者并且对文件系统的依赖性消失时,您可以使用模拟替换此类。另一方面,这真的很棒 以强类型的方式获取所有条目。

所以这个问题是幕后的代码生成问题,它与运行时无关。但是使用外部代码而不是注释生成代码对我来说似乎并不好。虽然我对注释不是很熟悉,但我想这可以实现(但我要记住,注释不能像McDowell那样生成类)

8 个答案:

答案 0 :(得分:3)

有无数的框架可以实现XML,并且需要不同程度的配置。与Java捆绑在一起的标准版本是JaxB,但它并不是一个单独的xml持久性框架......

问题是使用属性文件只能在最简单的类上比XML(或JSON,...)更好。当类变得有点复杂时,属性文件将成为一场噩梦。另一个问题是,使用普通类 - Xml和属性之间没有太大区别。

这意味着项目的范围将相当有限。对于具有大量简单属性文件的项目非常有用。

在我使用过的大型应用程序中,使用简单的工厂方法经常对属性文件进行强类型读取。

 Foo foo = Foo.loadFrom("foo.properties");

 class Foo {
    static Foo loadFrom(String fileName) {
         Properties props = new Properties();
         props.load(...);

         Foo foo = new Foo();
         foo.setKeyFoo(props.get("KeyFoo"));
         ...
         return foo;
    }
   ...
 }

答案 1 :(得分:2)

有一个somewhat similar project用于配置静态类型文件。它需要声明一个接口,但它填充了实现本身:

public interface AppConfig extends Config {
    long getTimeout ();
    URL getURL ();
    Class getHandlerClass ();
}

答案 2 :(得分:1)

注释处理工具(apt)不能修改类(尽管它可以创建新的类)。为了在编译时修改类,您可能需要编辑AST(如Project Lombok那样)。最简单的方法可能是生成类,然后使用生成的库作为其他代码的依赖项。

答案 3 :(得分:1)

类似于JFig(丑陋的IMO),Commons ConfigurationEasyConf

答案 4 :(得分:1)

另一种方法是使用执行此操作的数据绑定框架。即使是一个似乎不直接支持它的人也可以工作:例如,Jackson JSON处理器允许通过以下方式完成:

ObjectMapper m = new ObjectMapper();  MyBean bean = m.convertValue(properties,MyBean.class);  //(注意:需要来自trunk的最新代码;否则需要先写,回读)

只要属性映射中的条目与逻辑bean属性匹配,

就可以工作,并且可以将字符串值转换为匹配的基础值。

答案 5 :(得分:0)

如果你想静态地做,它的代码生成问题可以很容易地解决(对于文件中的每个项目,产生一个新的getXXX方法)。

但是如果你想在运行时使用它,那么你就会遇到在编译时没有存在代码引用方法的问题;我不认为可以做到。

(请注意,如果您正在寻找一个项目idead,反过来,具有访问器方法和注释的接口,以及在运行时生成的依赖于带注释的方法的实现,可以完成。)

答案 6 :(得分:0)

OP希望将属性文件映射到Java API,以使文件中的每个命名属性对应于API中类似命名的getter方法。我假设应用程序将使用此API来获取属性值,而不必使用属性名称字符串。

概念性问题是属性文件基本上不是静态类型的实体。每当有人编辑属性文件时,他们就可以添加新属性,从而更改属性文件的“类型”......并暗示相应API的签名。如果我们检查Java应用程序加载属性文件时没有意外的属性,那么我们有一个显式的动态类型检查。如果我们不检查意外(例如错误名称)的属性,我们就会遇到错误来源。如果您希望属性值的类型不是String,那么事情会变得更加混乱。

您可以正确执行此操作的唯一方法是为属性文件创建模式的概念,该文件指定属性名称和属性值的类型。然后实现一个属性文件编辑器,确保用户无法添加与架构冲突的属性。

此时我们应该认识到,更好的解决方案是使用XML作为属性文件表示,使用XML模式驱动的编辑器来编辑属性文件,使用JAXP或类似的东西将属性文件映射到Java API。

答案 7 :(得分:0)

我认为这可以解决您的问题 我已经写了去年的这个房产框架。 它将提供多种加载属性的方法,并且也可以强类型化。

查看http://sourceforge.net/projects/jhpropertiestyp/

它是开源的,完整记录的

以下是SourceForge的简短描述:

JHPropertiesTyped will give the developer strongly typed properties. Easy to integrate in existing projects. Handled by a large series for property types. Gives the ability to one-line initialize properties via property IO implementations. Gives the developer the ability to create own property types and property io's. Web demo is also available, screenshots shown above. Also have a standard implementation for a web front end to manage properties, if you choose to use it.

Complete documentation, tutorial, javadoc, faq etc is a available on the project webpage.