2016-02-08 61 views
4

我剛剛讀完AspectJ in Action並試圖寫入一些簡單的方面。我想編寫一個方面,它將爲使用EnumType.ORDINAL來保存數據庫的字段生成編譯時警告,但對於那些使用EnumType.STRING的字段則不會生成編譯時警告。我寫了類似的方面,但這是我嘗試在切入點中使用註釋的第一個方法,並且我做錯了什麼。我想爲JPA註釋生成一個給定值的編譯警告

我有如下所示的一個JPA2.1實體,並希望@Enumerated(EnumType.ORDINAL)註釋連接到myEnumFieldB生成一個編譯器警告......

import javax.persistence.Entity; 
import javax.persistence.Enumerated; 
import javax.persistence.EnumType; 

@Entity 
public class myEntity { 
    @Enumerated(EnumType.STRING) // I want this to compile ok 
    protected MyEnumType myEnumFieldA; 

    @Enumerated(EnumType.ORDINAL) // I want this to throw a warning 
    protected MyEnumType myEnumFieldB; 

    // primary key, other fields, getters & setters, etc. omitted 
} 

...這是副本我代碼嘗試幾個不同的切入點(註釋掉),並在它們旁邊包含錯誤消息。指定的切入點僅供最後一條註釋掉的行使用。

import javax.persistence.Enumerated; 
import javax.persistence.EnumType; 

public aspect DetectEnumPersistencePolicy { 
    pointcut ordinalEnumPersistence(Enumerated enumerated) 
     : @annotation(enumerated) && if(enumerated.value() == EnumType.ORDINAL); 
     // used below in a commented-out pointcut 

    declare warning 
     : @Enumerated(EnumType.ORDINAL) 
     //ERROR: Syntax error on token "Enumerated", "pointcut name" expected 

     //: @javax.persistence.Enumerated(javax.persistence.EnumType.ORDINAL) 
     //ERROR: Syntax error on token "javax", "pointcut name" expected 

     //: @Enumerated(EnumType.ORDINAL) * *.* 
     //ERROR: Syntax error on token "Enumerated", "pointcut name" expected 

     //: execution(@Enumerated(EnumType.ORDINAL) * *.*) 
     //ERROR: Syntax error on token ")", "(" expected 

     //: ordinalEnumPersistence(enumerated) 
     // ERROR: if() pointcut designator cannot be used in declare statement 

     : "Please consider using string persistence of enumerated types instead."; 
} 

我的想法至今都:

  1. 當我嘗試包括if(enumerated.value() == EnumType.ORDINAL)錯誤消息是if() pointcut designator cannot be used in declare statement。這使我認爲我不能使用切入點if(),因爲這將在運行時進行評估,但warning需要在編譯時生成(即使編譯時數據全部存在,因爲註釋的值不是隨運行時狀態而變化)?
  2. execution(@Enumerated(EnumType.ORDINAL) * *.*)相同,因爲執行發生在運行時。錯誤消息Syntax error on token ")", "(" expected對我來說沒有多大意義(它指的是第二個))。
  3. 如果我只是使用@annotation(enumerated)它應該在編譯時工作,但是我不知道如何在投擲警告之前執行檢查enumerated.value() == EnumType.ORDINAL
  4. 我已經嘗試在切入點@javax.persistence.Enumerated(javax.persistence.EnumType.ORDINAL)中使用完全限定的名稱,但仍收到錯誤消息Syntax error on token "javax", "pointcut name" expected
  5. 我試着將一些星號附加到切入點的註釋中,以指定我指的是@Enumerated(EnumType.ORDINAL) * *.*字段,但仍收到錯誤消息Syntax error on token "Enumerated", "pointcut name" expected

爲了完整起見,我在春天工具套件3.7.2正在處理與Java 1.8,並使用Maven來管理下面的AspectJ依賴關係:

<dependency> 
    <groupId>org.aspectj</groupId> 
    <artifactId>aspectjlib</artifactId> 
    <version>1.6.2</version> 
</dependency> 
<dependency> 
    <groupId>org.aspectj</groupId> 
    <artifactId>aspectjrt</artifactId> 
    <version>1.8.7</version> 
</dependency> 
<dependency> 
    <groupId>org.aspectj</groupId> 
    <artifactId>aspectjtools</artifactId> 
    <version>1.8.7</version> 
</dependency> 
<dependency> 
    <groupId>org.aspectj</groupId> 
    <artifactId>aspectjweaver</artifactId> 
    <version>1.8.7</version> 
</dependency> 

任何幫助,將不勝感激 - 我不能明白爲什麼@Enumerated(EnumType.ORDINAL)不起作用?

回答

2

其實你有一個基本問題:沒有切入點捕獲成員聲明,​​只能用於成員的讀/寫訪問。我正在分別討論get()set()。因此,你想攔截的是那些。試試這個:

虛擬輔助類,使示例代碼編譯:

package de.scrum_master.app; 

public class MyEnumType {} 

帶註釋的成員加上主要方法展示方面的Java類:

package de.scrum_master.app; 

import javax.persistence.Entity; 
import javax.persistence.EnumType; 
import javax.persistence.Enumerated; 

@Entity 
public class MyEntity { 
    @Enumerated(EnumType.STRING) // I want this to compile ok 
    protected MyEnumType myEnumFieldA; 

    @Enumerated(EnumType.ORDINAL) // I want this to throw a warning 
    protected MyEnumType myEnumFieldB; 

    public static void main(String[] args) { 
     MyEntity myEntity = new MyEntity(); 
     myEntity.myEnumFieldA = new MyEnumType(); 
     System.out.println(myEntity.myEnumFieldB); 
    } 
} 

,你可以請參閱myEnumFieldB在最後一行中訪問一次。這應該會引發編譯器警告。

看點:

package de.scrum_master.aspect; 

import javax.persistence.Enumerated; 
import javax.persistence.EnumType; 

public aspect DetectEnumPersistencePolicy { 
    pointcut ordinalEnumPersistence() : 
     set(@Enumerated(value=EnumType.ORDINAL) * *) || 
     get(@Enumerated(value=EnumType.ORDINAL) * *); 

    declare warning : ordinalEnumPersistence() : 
     "Please consider using string persistence of enumerated types instead."; 
} 

這就是你會在Eclipse中看到:

Eclipse compiler warning

相關問題