7

Przykład użycia:
Chcę umieścić w polach klasy niestandardową adnotację @MyContainer, a następnie automatycznie dodać na wszystkich takich polach odpowiednie adnotacje Hibernate (w zależności od typu pola i właściwości).
Dodatkowo muszę dodać adnotację XmlType JAXB do klasy i oprzeć nazwę typu na nazwie klasy.
Chciałbym dodatkowo dodać adnotacje do pól w oparciu o ich typy itp. Wszystkie dodane adnotacje powinny być dostępne w czasie wykonywania (więc hibernacja/JAXB może je znaleźć).
Zdaję sobie sprawę z następujących opcji:Dodawanie programowych adnotacji do klasy Java

  1. Pre-processing źródło klasy (zła opcja)
  2. Processing podczas kompilacji z javax.annotation.processing API
  3. postu manipulacji kompilacji przy użyciu narzędzi takich jak Java Pomagają
  4. Manipulacja klasy podczas załadunku z java.lang.instrument API
  5. robi to z AspectJ (nie wystarczająco silne)

Moje główne cele to:

  1. zachować synchronizację między klasą i źródło do debugowania
  2. obsługują działa zarówno Maven i Eclipse IDE (/ IntelliJ)

Będę wdzięczny, jeśli ludzie, którzy już zrobione takie rzeczy mogą zalecić najlepsze podejście do takiego zadania (i być może potencjalne pułapki).

+0

A co z brakiem generowania adnotacji, ale zamiast generowania plików XML mapowania hibernacji (hbm.xml), które można załadować za pomocą konfiguracji hibernacji? – Strelok

+0

Dzięki, to jest dobry pomysł, ale wolę opcję adnotacji w moim przypadku, ponieważ muszę generować adnotacje JAXB (i być może inne w przyszłości). –

Odpowiedz

0

Uważam, że preferowane są źródła klasy preprocesorów. Pozwala to na zsynchronizowanie źródeł ze skompilowanymi klasami, co jest dobre do debugowania, o czym wspomniałeś. Ale jest również dobre dla kontroli wersji, ponieważ możesz sprawdzić wygenerowane adnotacje. Jest także o wiele trudniejsze odnalezienie problemów w twoim narzędziu, jeśli jest on uruchamiany podczas kompilacji. Obsługa IDE nie powinna stanowić problemu przy generowaniu kodu w fazie generowania źródeł.

Edit: Szybkie wyszukiwanie przyniosły jakieś info o programowym java modyfikacji źródłowego using the eclipse jdt lub some thing in netbeans. Ale może to być warte więcej badań lub własnych pytań.

+0

Dzięki za odpowiedź. Czy możesz podać więcej informacji na temat rozwiązania, na przykład, które narzędzie można wykorzystać do analizy kodu źródłowego i manipulowania nim? Wadą jest to, że kod źródłowy jest wypełniony adnotacjami o niskim poziomie i jest mniej czytelny (pomyślałem o dodaniu adnotacji tylko dla środowiska wykonawczego). –

+0

Jeśli obawiasz się, że może to prowadzić do powstania nieczystego kodu, powinieneś rozważyć użycie interfejsu swojej obecnej klasy i ukryć implementację za pomocą adnotacji w jak największym stopniu. – SpaceTrucker

0

Chcę zaproponować inne podejście w tej sprawie. Ponieważ mój first answer może wymagać zakodowania własnego narzędzia, możesz również wypróbować znacznie prostsze rozwiązanie. Ponieważ mam nadzieję, że przeprowadzasz testy swoich klas, możesz zaimplementować klasę podstawową dla każdego testu jednostkowego dla takiej klasy. W tej klasie bazowej znajduje się metoda testowania, która sprawdza, czy każde pole opatrzone komentarzem zawiera także wymagane adnotacje typu hibernate.

Zasadniczo zrobiliśmy to samo, nie dla adnotacji, ale dla możliwości serializacji pól i całkiem nieźle sobie z tym radziliśmy.

0

Aby działał najbardziej przejrzysty w IDE, kompilacji linii poleceń i podczas wykonywania, opcja 1 (przy użyciu APT) i opcja 5 (przy użyciu AspectJ) dadzą najlepsze dopasowanie.

W przypadku opcji 1 konieczne będzie wdrożenie własnego procesora adnotacji, który wprowadzi dodatkowe adnotacje na podstawie obecności własnej adnotacji @MyContainer.Oto przykład tego podejścia zastosowanego dla something similar.

Dla opcji 5 można po prostu użyć annotation declaration. Coś w tym stylu:

Narzędzie Spring Roo szeroko wykorzystuje opcję 5 iz pewnością nie mogę powiedzieć, że nie jest wystarczająco mocne.

+0

Czy możesz podstawić parametry adnotacji i adnotacji do informacji o klasie/metodzie/pręcie? Na przykład muszę zbadać typ danych kontenera i wybrać kilka możliwych adnotacji w trybie hibernacji. Dodatkowo muszę wygenerować nazwy kolumn do hibernacji adnotacji na podstawie nazw pól itp. ... –

0

Istnieje kilka alternatyw wymienionych powyżej, z których każda ma swoje zalety i wady. Dlatego nie sądzę, by istniała prawdziwa "właściwa" odpowiedź na powyższe pytanie. Moim celem było zdobycie wkładów od społeczności i od ludzi, którzy robili takie rzeczy w przeszłości i mają doświadczenie. Osobiście zdecydowałem się użyć Instrument API z Javassist. W ten sposób klasy są rozszerzane w czasie wykonywania (chociaż to samo narzędzie może być używane do przetwarzania po kompilacji). Zaletą jest to, że agent można załadować z wnętrza JVM, co pozwala uniknąć obsługi wszystkich linii poleceń. Wspaniale będzie usłyszeć o innych alternatywach.
Dzięki
Avner

0

Oto przykład kodu do definiowania niestandardowego adnotacji. Ta @TesterInfo jest stosowana na poziomie klasy, przechowuj szczegóły testera. To pokazuje różne użycie typów zwracanych - enum, array i string.

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"; 

}