当前位置: 首页 > 知识库问答 >
问题:

通过自定义注释注入常量

宗政海
2023-03-14

我在整个代码中有一堆常量,用于系统的各种可调整属性。我正在将它们全部移动到一个中央. Properties文件中。我目前的解决方案是有一个Properties.java静态加载. Properties文件并公开各种getter方法,如下所示:

public class Properties {
    private static final String FILE_NAME = "myfile.properties";
    private static final java.util.Properties props;

    static {
        InputStream in = Properties.class.getClassLoader().getResourceAsStream(
                FILE_NAME);
        props = new java.util.Properties();
        try {
            props.load(in);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static String getString(Class<?> cls, String key) {
        return props.getProperty(cls.getName() + '.' + key);
    }

    public static int getInteger(Class<?> cls, String key) {
        return Integer.parseInt(getString(cls, key));
    }

    public static double getDouble(Class<?> cls, String key) {
        return Double.parseDouble(getString(cls, key));
    }
}

唯一的问题是,对于我从这个文件中获得的每个常量,我都有一些样板:

private final static int MY_CONSTANT = Properties.getInteger(
    ThisClass.class, "MY_CONSTANT");

我不认为我想使用Spring或类似的东西,因为那看起来更像是boilerplae。我希望使用自定义注释来解决这个问题。我找到了这个教程,但是我真的不能弄清楚如何从注释处理中获得我想要的功能。Java文档更没有帮助。不过,这应该是我在编译时应该能够做的事情。我知道类和字段的名称。

我的想法是这样的:

@MyAnnotation
private static final int MY_CONSTANT;

有人知道我会怎么做,或者至少知道我想做什么的最佳实践吗?

共有2个答案

赵献
2023-03-14

实际上还不太清楚为什么要归档,以及要归档什么。

正如我正确理解的那样,您需要使用特殊类型的注释来自动为某些属性文件中的静态最终常量赋值。不幸的是,没有特殊的黑客是不可能的。注释与此无关。

原因是final字段必须初始化,这是编译器的请求。java中没有特殊的注释可以提供您想要的语法糖。

但是如果你坚持这样做,有两种方法:

>

更少的外部方式:拒绝属性字段的最终修饰符请求,只使用反射填充这些字段值。

此外,对于这些方法,可以使用注释。但您必须解决以下技术问题:

1) 在类路径中查找所有类中的所有字段,这些字段用特殊的注释进行注释。查看:使用反射获取类路径中的所有类,并获取带有注释的字段列表

2) 强制在应用程序的所有可能输入点初始化属性类。在这个类的静态部分,你们将加载你们的属性文件,然后使用(1)反射和类加载器方法,给所有常量赋值。

卫松
2023-03-14

首先,你不应该这么做。它很实用,但太粗糙,如果你想用不同的设置编写测试,你会遇到问题。而且,没人会明白它是怎么工作的。

注释处理器可能对您无能为力。Lombok风格的黑客处理器可以。你想做什么

@MyAnnotation
private static final int MY_CONSTANT;

像这样工作

private final static int MY_CONSTANT =
    Properties.getInteger(ThisClass.class, "MY_CONSTANT");

原始表达式不会编译(由于未初始化的final变量),但它解析得很好,Lombok可以完成它的工作。这里已经有了一些相关的东西:

  • @值将修饰符更改为final private

所以实际上,你可以写

@MyAnnotation
int MY_CONSTANT;

让你的注释也改变修改器。我会看看eclipse和javac处理程序的@UtilityClass,我想你需要做的就是生成初始值设定项(这是相当多的工作,因为它非常复杂)。

我认为龙目山本身不会很快实现这一点,因为

  • 所有的静态内容都是不可测试的,而且大多是糟糕的风格
  • 并不是每个人都想在他们的代码中包含这一点
  • 没有那么多陈词滥调
  • 它还神奇地引用了类属性,但这可以通过配置来解决

但我想捐款可能会被接受。

 类似资料:
  • 我是Spring Security的新手。我看过很多关于如何通过外部属性文件的注释注入值的文章。我尝试了很多方法,但最终都是用java。lang.IllegalArgumentException:无法解析占位符“val.id”异常。 你能给我一些提示如何处理这个例外吗? 我的java类如下所示: 我的属性文件名为val.properties,位于WEB-INF下,其内容为val.id=xyz 我将

  • 使用 Vim 编辑 Shell 脚本,在进行调试时,需要进行多行的注释,每次都要先切换到输入模式,在行首输入注释符"#"再退回命令模式,非常麻烦。 连续行的注释其实可以用替换命令来完成。换句话说,在指定范围行加"#"注释,可以使用 ":起始行,终止行 s/^/#/g",例如: :1,10s/^/#/g 表示在第 1~10 行行首加"#"注释。"^"意为行首;"g"表示执行替换时不询问确认。如果希望

  • 目前,我将辅助注射与命名参数一起使用,如下所示: 这很棒。但是我认为使用字符串作为参数的标识符有点难看。我想做的是以下内容: 所以本质上我想要自定义辅助注释。有办法做到这一点吗?

  • 问题内容: 我为我写了一个 对于每个我使用以下注释 因此,我决定定义自己的注释女巫,其中包含所有这样的注释 然后,我只用了一个注释 修改后,测试失败 为了使其再次工作,需要我将其添加到 我的问题是为什么我的注释包含注释时不起作用?注释有什么特别之处吗?还是我错过了什么? PS:我使用相同的方法,它们也很好用。 问题答案: 这种机制是Spring框架特有的,在这种机制中,您可以使用本身带有其他注释的

  • > 我不能使基本包属性是动态的,即我不能传递,但需要在配置中预先定义包。 我查看了,但无法使其工作。 当我忽略基本包时,扫描从注释的定义包开始,而不是从注释类的包开始。在上面的示例中,它只扫描并创建中类的bean,而不扫描并创建中的bean。 如果将放在类上,则一切都可以工作,但当将其移动到的元注释时,将停止工作。如何告诉Spring Framework将视为使用某些默认值指定的另一种方式。我尝试

  • 问题内容: 注释如何与Java一起使用?以及如何创建这样的自定义注释: 基本上,我需要保留的POJO在持久化时像这样进行序列化: 这样,实际的生成/持久对象是这样的: 任何想法如何实现这一点? 问题答案: 如果创建自定义注释,则必须使用此处的 API 示例进行处理。您可以参考如何声明注释。 这是Java中的示例注释声明的样子。 并被称为。 表示您想在运行时保留注释,并且可以在运行时访问它。 表示您