繁体   English   中英

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

[英]Java pre-processor for sharing code in annotations

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

我想知道是否有任何Java预处理器可以与Maven很好地配合?

您可以尝试我的预处理器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!" );
    }
}

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

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

这导致某种形式的注释地狱(例如,我在想关于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)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM