用于在注释中共享代码的Java预处理器

时间:2013-10-15 15:21:42

标签: java annotations preprocessor

Java注释中的属性必须是完全静态的表达式,但由于该语言缺乏预处理功能,因此注释中的代码重用基本上不存在。

例如,以下用例没有其他选择:

#define GRANTED {"group1", "group2"}

@Access(granted = GRANTED)
public void ...

#define USER_HAS_ACCESS(userArg, permissions) "arguments." + userArg + ".hasAccess(" + permissions + ")"

@Access(grantedIf = USER_HAS_ACCESS("usr", "modify"))
public void modifyData(User usr, Data d) ...

在这些情况下,必须在使用注释的每个位置重新生成由宏替换的代码(因为Java中没有数组常量且没有编译时字符串格式化),这是一个很大的维护问题。 / p>

我想知道是否有适用于Maven的Java预处理器?

2 个答案:

答案 0 :(得分:1)

你可以尝试我的预处理器https://github.com/raydac/java-comment-preprocessor它支持maven 示例(不是最佳解决方案,但它有效)

package com.mycompany.mavenproject1;

//#local GRANTED="\"new\")"

@Anno(/*$GRANTED$*//*-*/"default to be used without preprocessor")
public class App 
{

    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
    }
}

答案 1 :(得分:0)

请注意,如果注释内容是静态的,则可能相当复杂。 实际上,注释内容可以是

  • 字符串
  • 枚举
  • 另一个注释
  • 甚至数组

导致某种注释地狱(我想,作为一个例子,关于JPA named queries)。

此外,正如您所要求的那样,我对EJB安全模型的强烈提醒,我将采取更多示例。

任何用户都可以自由地使用EJB(使用......没有,这是默认值),或者可以使用@RolesAllowed({"roleA", "roleB", "roleC"})将其访问权限限制为某些角色。此外,由于此处使用的字符串只是Java常量,因此可以在“常量接口”中声明它们,仅声明那些角色

public interface Roles {
    String ROLE_A = "roleA";
    String ROLE_B = "roleB";
    String ROLE_C = "roleC";
}

然后,我的初始声明变为@RolesAllowed({Roles.ROLE_A, Roles.ROLE_B, Roles.ROLE_C})。然而,这并没有详细说明这些角色如何应用于用户...这导致我们直接进入JAAS地狱(我不会把你推到一个地狱......好吧,除非你想要摆脱你的预处理器的想法 - 位于另一个地狱圈: - ))。

无论如何,让我非常清楚地说明一点:注释只是声明性的,它们可以/应该只包含意图声明,而不是行为。你当然可以进行字符串解析来检测内容并操作require行为,但它特别是糟糕的想法。如果您完全相信您需要预处理器,请至少用另一个注释替换字符串片段:

#define USER_HAS_ACCESS(userArg, permissions) @Allow(userName=userArg, granted=permissions)

但是......等等,我已经宣布了一个注释来简化预处理?也许是因为这两件事情有很大的重叠:-)事实上,在超类中声明注释并将其应用于所有后代类是一些常识......