0

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 中没有数组常量和编译时字符串格式),这是一个很大的维护问题。

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

4

2 回答 2

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!" );
    }
}
于 2013-10-28T17:46:20.603 回答
0

请注意,如果注释内容是静态的,那么它可能会相当复杂。确实,注释内容可以

  • 细绳
  • 枚举
  • 数字
  • 另一个注释
  • 甚至是一个数组

这会导致某种注释地狱(例如,我在想关于JPA 命名查询)。

此外,由于您的要求使我强烈地想起了 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 地狱(我不会把你推到这个地狱......好吧,除非你想摆脱你的预处理器的想法——它位于另一个地狱的圈子里:-))。

无论如何,让我非常清楚地表明一点:注释只是声明性的,它们可以/应该只包含意图声明,而不是行为。您当然可以进行字符串解析来检测内容并操作所需的行为,但这确实是个主意。如果您绝对确信您需要您的预处理器,请至少用另一个注释替换字符串片段:

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

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

于 2013-10-15T15:50:10.360 回答