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