7

用法示例:
我想在類字段上添加一個自定義註釋@MyContainer,然後自動在所有這些字段上添加相關的Hibernate註釋(取決於字段類型和屬性)。
另外我需要將JAXB XmlType註釋添加到類中,並將類名稱作爲類名稱。
我想另外添加註釋到字段基於他們的類型等。 所有添加的註釋應該在運行時可用(因此hibernate/JAXB可以找到它們)。
我知道以下選項:將編程註釋添加到Java類

  1. 預處理類源(壞的選擇)
  2. 處理編譯期間javax.annotation.processing中的API
  3. 後編譯操縱的工具,如Java類加載與java.lang.instrument中的API
  4. 使用AspectJ(不夠強大)
否則它在幫助
  • 操縱

    我的主要目標是:

    1. 保留類和源極之間的同步進行調試
    2. 支持來自Maven和IDE(Eclipse中/的IntelliJ)工作

    ,我會很感激,如果誰的人已經做過這樣的事情可以爲這樣的任務推薦最好的方法(也許是潛在的陷阱)。

  • +0

    怎麼樣不生成註釋,而是生成可以通過休眠配置加載的hibernate映射XML文件(hbm.xml)? – Strelok 2012-07-22 14:08:20

    +0

    謝謝,這是一個好主意,但我更喜歡我的情況下的註釋選項,因爲我還需要生成JAXB註釋(以及將來可能還有其他註解)。 – 2012-07-22 14:30:29

    回答

    0

    我認爲預處理類源應該是您的首選方式。這使您可以將源與編譯的類同步,這對您在前面提到的調試很有幫助。但它也適用於版本控制,因爲您可以檢查那些生成的註釋。如果它在編譯期間運行,那麼追蹤工具中的問題也更加困難。在生成源代碼階段運行代碼生成時,IDE支持也應該沒有問題。

    編輯: 快速搜索產生約程序的Java源修改 using the eclipse jdtsome thing in netbeans一些相關信息。但是,這可能值得更多的研究或自己的問題。

    +0

    感謝您的回答。您能否提供關於解決方案的更多信息,例如哪些工具可用於分析源代碼並對其進行處理?不利的一面是源代碼被低級別的註釋填充,不太清晰(我想爲運行時添加註釋)。 – 2012-07-23 01:00:07

    +0

    如果您擔心這會導致代碼不乾淨,您應該考慮使用當前類的接口並儘可能使用註釋隱藏實現。 – SpaceTrucker 2012-07-23 07:07:23

    0

    我想提出另一種方法。由於我的first answer可能涉及到編寫自己的工具,您也可以嘗試一個更簡單的解決方案。正如我希望你是單元測試你的類,你可以爲這樣的類的每個單元測試實現一個基類。在這個基類中有一個測試方法,它檢查每個使用@MyContainer註解的字段是否也具有所需的hibernate註釋。

    我們基本上做了同樣的事情,不是用於註釋,而是用於字段的可序列化,並且用這種方法運行得很好。

    0

    爲了讓它在IDE,命令行構建和運行時更加透明,選項1(使用APT)和選項5(使用AspectJ)將爲您提供最佳配置。

    對於選項1,您必須實現自己的註釋處理器,該處理器將根據您自己的@MyContainer註釋的存在注入其他註釋。這是用於something similar的這種方法的一個例子。

    對於選項5,您可以簡單地使用annotation declaration。這樣的事情:

    declare @field : * ((@*..MyContainer *)).*(..) : @OtherAnnotation(); 
    

    Spring's Roo工具廣泛使用選項5,我當然不能說它不夠強大。

    +0

    您可以將註釋和註釋參數基於類/方法/成員信息嗎?例如,我需要檢查容器數據類型並選擇幾個可能的休眠註釋。另外我需要爲基於字段名稱的hibernate註釋生成列名稱...... – 2012-07-25 06:19:07

    0

    上面提到的幾種替代方案各有其優點和缺點。這就是爲什麼我不認爲上述問題有真正的「正確」答案。我的目的是從社區和過去曾經做過這類事情並有過經驗的人那裏獲得投入。就我個人而言,我選擇使用帶有Javassist的Instrument API。通過這種方式,類可以在運行時進行擴展(儘管可以使用相同的工具進行後期編譯處理)。好處是代理可以從JVM內部加載,避免處理所有的命令行。能聽到其他選擇會很高興。
    謝謝,
    Avner

    0

    以下是定義自定義註釋的代碼示例。這個@TesterInfo應用於課堂級別,存儲測試人員的詳細信息。這顯示了返回類型的不同用法 - 枚舉,數組和字符串。

    package com.mkyong.test.core; 
    
    import java.lang.annotation.ElementType; 
    import java.lang.annotation.Retention; 
    import java.lang.annotation.RetentionPolicy; 
    import java.lang.annotation.Target; 
    
    @Retention(RetentionPolicy.RUNTIME) 
    @Target(ElementType.TYPE) //on class level 
    public @interface TesterInfo { 
    
        public enum Priority { 
         LOW, MEDIUM, HIGH 
        } 
    
        Priority priority() default Priority.MEDIUM; 
    
        String[] tags() default ""; 
    
        String createdBy() default "Mkyong"; 
    
        String lastModified() default "03/01/2014"; 
    
    }