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

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 地獄 (私があなたを突き落とすことのない地獄) に突入することになります。プリプロセッサのアイデア - これは別の地獄の輪の中にあります :-))。

とにかく、非常に明確に 1 つのポイントを立てさせてください。注釈は単に宣言的であり、意図の宣言のみを含めることができます/含めるべきであり、動作は含みません。もちろん、コンテンツを検出して必要な動作を操作するために文字列の解析を行うことはできますが、それは特に悪い考えです。プリプロセッサが必要だと確信している場合は、少なくとも文字列フラグメントを別の注釈に置き換えてください。

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

しかし...待って、その前処理を簡素化するために注釈を宣言しましたか? おそらく、これら2つのことが大きく重複しているためです:-)実際、スーパークラスで宣言され、そのすべての子孫クラスに適用される注釈を持つことは、いくつかの常識です...

于 2013-10-15T15:50:10.360 に答える