Konfiguracja XML a konfiguracja oparta na adnotacjach [zamknięte]

132

W kilku dużych projektach, nad którymi ostatnio pracowałem, coraz ważniejsze staje się wybranie jednego lub drugiego (XML lub Adnotacja). W miarę rozwoju projektów spójność jest bardzo ważna dla łatwości konserwacji.

Moje pytania to: jakie są zalety konfiguracji opartej na XML w porównaniu z konfiguracją opartą na adnotacjach i jakie są zalety konfiguracji opartej na adnotacjach w porównaniu z konfiguracją opartą na XML?

abarax
źródło
Zakładając, że masz na myśli adnotacje typu @Componenti @Autowired, jest to fałszywa dychotomia. Istnieją inne sposoby tworzenia konfiguracji, w tym JavaConfig i groovy config.
Bacar
Sprawdź też ten stackoverflow.com/questions/8428439/…
pramodc84

Odpowiedzi:

199

Adnotacje mają swoje zastosowanie, ale nie są jedyną srebrną kulą, która zabija konfigurację XML. Polecam zmieszanie tych dwóch!

Na przykład, jeśli używasz Springa, całkowicie intuicyjnie jest używać XML jako części aplikacji polegającej na wstrzykiwaniu zależności. To powoduje, że zależności kodu są oddzielone od kodu, który będzie go używał, natomiast użycie pewnego rodzaju adnotacji w kodzie, który wymaga zależności, uświadamia kodowi tę automatyczną konfigurację.

Jednak zamiast używać XML do zarządzania transakcjami, oznaczanie metody jako transakcyjną z adnotacją ma sens, ponieważ jest to informacja, którą programista prawdopodobnie chciałby znać. Ale interfejs zostanie wstrzyknięty jako PodtypY zamiast PodtypuX, nie powinien być uwzględniany w klasie, ponieważ jeśli teraz chcesz wstrzyknąć SubtypeX, musisz zmienić swój kod, podczas gdy i tak miałeś wcześniej kontrakt interfejsu, więc w przypadku XML wystarczy zmienić mapowania XML, a jest to dość szybkie i bezbolesne.

Nie używałem adnotacji JPA, więc nie wiem, jakie są dobre, ale twierdziłbym, że pozostawienie mapowania fasoli do bazy danych w XML jest również dobre, ponieważ obiekt nie powinien przejmować się skąd pochodzą jego informacje , powinien po prostu dbać o to, co może zrobić z jego informacjami. Ale jeśli lubisz JPA (nie mam z tym żadnego doświadczenia), zdecydowanie idź na to.

Ogólnie: jeśli adnotacja zapewnia funkcjonalność i działa jako komentarz sama w sobie i nie wiąże kodu z jakimś konkretnym procesem, aby normalnie funkcjonować bez tej adnotacji, przejdź do adnotacji. Na przykład metoda transakcyjna oznaczona jako transakcyjna nie zabija logiki działania i służy również jako dobry komentarz na poziomie kodu. W przeciwnym razie informacje te prawdopodobnie najlepiej można wyrazić w formacie XML, ponieważ chociaż ostatecznie wpłyną one na sposób działania kodu, nie zmieni to głównej funkcjonalności kodu, a zatem nie będą znajdować się w plikach źródłowych.

MetroidFan2002
źródło
Dzięki za świetną odpowiedź! Miałem trudności z podjęciem decyzji, którego użyć. Ta odpowiedź SO mówi, że promują oddzielenie, podczas gdy ten post na blogu mówi, że promują ścisłe powiązanie! Twoja odpowiedź naprawdę wyjaśniła mi problem.
Mikayla Maki
5
Podsumowałbym tę radę następująco: używaj adnotacji dla AOP (transakcje mogą być traktowane na przykład jako aspekt), ale nie używaj ich do wstrzykiwania zależności.
Bacar
1
Czy ta odpowiedź jest nadal aktualna w dzisiejszych czasach (2015)?
sp00m
1
w większości przypadków dla większości ludzi preferowane są adnotacje
Junchen Liu
31

Jest tu szersza kwestia, dotyczy zewnętrznych i wbudowanych metadanych. Jeśli twój model obiektowy ma być utrwalony tylko w jeden sposób, to wbudowane metadane (tj. Adnotacje) są bardziej zwarte i czytelne.

Jeśli jednak model obiektowy został ponownie wykorzystany w różnych aplikacjach w taki sposób, że każda aplikacja chciała utrwalić model na różne sposoby, wówczas eksternalizacja metadanych (tj. Deskryptorów XML) staje się bardziej odpowiednia.

Żaden z nich nie jest lepszy, więc oba są obsługiwane, chociaż adnotacje są bardziej modne. W rezultacie nowe struktury typu hair-on-fire, takie jak JPA, zwykle kładą na nie większy nacisk. Bardziej dojrzałe API, takie jak natywny Hibernate, oferują oba, ponieważ wiadomo, że żadne z nich nie jest wystarczające.

skaffman
źródło
13

Zawsze myślę o adnotacjach jako o pewnym wskaźniku tego, do czego zdolna jest klasa lub jak współdziała z innymi.

Z drugiej strony konfiguracja Spring XML to dla mnie właśnie taka konfiguracja

Na przykład informacje o adresie IP i porcie serwera proxy są z pewnością umieszczane w pliku XML, jest to konfiguracja środowiska wykonawczego.

Użycie @Autowire, @Elementdo wskazania struktury, co zrobić z klasą, jest dobrym użyciem adnotacji.

Umieszczenie adresu URL w @Webserviceadnotacji to zły styl.

Ale to tylko moja opinia. Granica między interakcją a konfiguracją nie zawsze jest jasna.

Huibert Gill
źródło
Konfiguracja oparta na adnotacjach i adnotacjach (konfiguracja Java) to dwie różne rzeczy, a OP pyta o późniejszą, podczas gdy ty mówisz o pierwszej.
Lucky
6

Używam Springa od kilku lat i ilość potrzebnego XML-a była zdecydowanie uciążliwa. Pomiędzy nowymi schematami XML a obsługą adnotacji w Spring 2.5 zwykle robię następujące rzeczy:

  1. Używanie „skanowania komponentów” do automatycznego ładowania klas, które używają @Repository, @Service lub @Component. Zwykle nadaję każdej fasoli nazwę, a następnie łączę je ze sobą za pomocą @Resource. Uważam, że ta hydraulika nie zmienia się zbyt często, więc adnotacje mają sens.

  2. Używanie przestrzeni nazw „aop” dla wszystkich AOP. To naprawdę działa świetnie. Nadal używam go również do transakcji, ponieważ umieszczanie @Transactional w każdym miejscu jest trochę męczące. Możesz tworzyć nazwane punkty dla metod w dowolnej usłudze lub repozytorium i bardzo szybko zastosować porady.

  3. Używam LocalContainerEntityManagerFactoryBean wraz z HibernateJpaVendorAdapter do skonfigurowania Hibernate. Pozwala to Hibernate na łatwe automatyczne wykrywanie klas @Entity w ścieżce klas. Następnie tworzę nazwany bean SessionFactory przy użyciu „factory-bean” i „factory-method” odnoszących się do LCEMFB.

cliff.meyers
źródło
5

Ważną częścią stosowania podejścia opartego wyłącznie na adnotacjach jest to, że pojęcie „nazwy fasoli” mniej więcej znika (staje się nieistotne).

„Nazwy fasoli” w Spring tworzą dodatkowy poziom abstrakcji w stosunku do klas implementujących. W przypadku komponentów bean XML definiuje się i odwołuje do ich nazwy. Z adnotacjami odwołuje się do nich ich klasa / interfejs. (Chociaż nazwa fasoli istnieje, nie musisz jej znać)

Jestem głęboko przekonany, że pozbycie się zbędnych abstrakcji upraszcza systemy i poprawia produktywność. Myślę, że w przypadku dużych projektów korzyści wynikające z pozbycia się XML mogą być znaczące.

krosenvold
źródło
5

Myślę, że widoczność to wielka wygrana dzięki podejściu opartemu na XML. Uważam, że XML nie jest naprawdę zły, biorąc pod uwagę różne narzędzia do nawigacji w dokumentach XML (tj. Okno Struktura plików programu Visual Studio + ReSharper).

Z pewnością możesz przyjąć podejście mieszane, ale wydaje mi się to niebezpieczne, choćby dlatego, że potencjalnie utrudniłoby nowym programistom w projekcie ustalenie, gdzie różne obiekty są skonfigurowane lub zmapowane.

Nie wiem; ostatecznie Piekło XML nie wydaje mi się takie złe.

Charles Chen
źródło
4

Zależy to od wszystkiego, co chcesz skonfigurować, ponieważ istnieją opcje, których nie można skonfigurować za pomocą adnotacji. Jeśli widzimy to z boku adnotacji:

  • plus: adnotacje są mniej gadatliwe
  • minus: adnotacje są mniej widoczne

To od Ciebie zależy, co jest ważniejsze ...

Ogólnie polecam wybrać jeden sposób i zastosować go na całej zamkniętej części produktu ...

(z pewnymi wyjątkami: np. jeśli wybierzesz konfiguracje oparte na XML, możesz użyć adnotacji @Autowire. To mieszanie, ale ta pomaga zarówno w czytelności, jak i łatwości utrzymania)

Juraj
źródło
4

Istnieją inne aspekty do porównania, takie jak refaktoryzacja i inne zmiany kodu. podczas korzystania z XML wykonanie refaktoryzacji wymaga poważnego wysiłku, ponieważ musisz zadbać o całą zawartość XML. Ale jest to łatwe, gdy używasz adnotacji.

Moim preferowanym sposobem jest konfiguracja oparta na Javie bez (lub minimalne) adnotacje. http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-java

takacsot
źródło
3

Mogę się mylić, ale pomyślałem, że Adnotacje (jak w @Tag w Javie i [Atrybut] w języku C #) były opcją kompilacji, a XML - w czasie wykonywania. To dla mnie mówi, że nie są równoważne i mają różne wady i zalety.

ARKBAN
źródło
Fakt, że adnotacje są kwestią czasu kompilacji, jest zaletą konfiguracji opartej na adnotacjach, jednak zarówno adnotacje, jak i XML są metodami konfiguracji iw tym kontekście osiągają to samo. na przykład. konfigurowanie odwzorowań hibernacji w pliku xml w przeciwieństwie do używania adnotacji w klasie.
abarax
Ahhh, widzę swoje zmieszanie. Pytanie wprowadziło mnie w błąd, myśląc, że opisuje konfigurację danych wykraczających poza metadane klasy.
ARKBAN
3

Myślę też, że najlepszy jest miks, ale to też zależy od rodzaju parametrów konfiguracyjnych. Pracuję nad projektem Seam, który również używa Springa i zwykle wdrażam go na różnych serwerach deweloperskich i testowych. Więc podzieliłem:

  • Konfiguracja specyficzna dla serwera (podobnie jak bezwzględne ścieżki do zasobów na serwerze): plik Spring XML
  • Wstrzykiwanie fasoli jako członków innych fasoli (lub ponowne użycie wartości zdefiniowanej przez Spring XML w wielu ziarnach): Adnotacje

Kluczowa różnica polega na tym, że nie musisz ponownie kompilować kodu dla wszystkich zmieniających się konfiguracji specyficznych dla serwera, po prostu edytuj plik xml. Zaletą jest również to, że niektóre zmiany konfiguracji mogą być wprowadzane przez członków zespołu, którzy nie rozumieją całego kodu.

Cristian Vat
źródło
2

W zakresie kontenera DI uważam, że DI oparty na adnotacjach nadużywa adnotacji Java. Mówiąc to, nie polecam szerokiego stosowania go w Twoim projekcie. Jeśli Twój projekt naprawdę potrzebuje mocy kontenera DI, polecam użycie Spring IoC z opcją konfiguracyjną opartą na Xml.

Jeśli jest to tylko ze względu na test jednostkowy, programiści powinni zastosować wzorzec Dependency Inject w swoim kodowaniu i wykorzystać narzędzia do mockowania, takie jak EasyMock lub JMock, aby obejść zależności.

Należy starać się unikać używania kontenera DI w niewłaściwym kontekście.

Thang
źródło
2

Informacje konfiguracyjne, które zawsze będą połączone z określonym komponentem Java (klasą, metodą lub polem), są dobrym kandydatem do przedstawienia za pomocą adnotacji. Adnotacje działają szczególnie dobrze w tym przypadku, gdy konfiguracja jest kluczowa dla celu kodu. Ze względu na ograniczenia adnotacji najlepiej jest również, gdy każdy komponent może mieć tylko jedną konfigurację. Jeśli musisz poradzić sobie z wieloma konfiguracjami, szczególnie tymi, które są uzależnione od czegokolwiek spoza klasy Java zawierającej adnotację, adnotacje mogą powodować więcej problemów niż rozwiązują. Wreszcie adnotacje nie mogą być modyfikowane bez ponownej kompilacji kodu źródłowego Java, więc nic, co wymaga rekonfiguracji w czasie wykonywania, nie może używać adnotacji.

Proszę zapoznać się z poniższymi linkami. Mogą się też przydać.

  1. Adnotacje a XML, zalety i wady
  2. http://www.ibm.com/developerworks/library/j-cwt08025/
tharindu_DG
źródło
1

To jest klasyczne pytanie „Konfiguracja kontra Konwencja”. W większości przypadków indywidualny gust dyktuje odpowiedź. Jednak osobiście wolę konfigurację (tj. Opartą na XML) od Konwencji. IMO IDE są wystarczająco solidne, aby przezwyciężyć niektóre z piekła XML, które ludzie często kojarzą z budowaniem i utrzymywaniem podejścia opartego na XML. Ostatecznie uważam, że korzyści wynikające z konfiguracji (takie jak tworzenie narzędzi do budowania, utrzymywania i wdrażania pliku konfiguracyjnego XML) w dłuższej perspektywie przeważają nad konwencją.

Jason
źródło
6
Myślę, że „Konfiguracja kontra Konwencja” jest ortogonalna w tej kwestii. Zarówno adnotacje, jak i pliki XML mają wiele rozsądnych ustawień domyślnych (konwencji), które znacznie upraszczają ich użycie. Prawdziwa różnica polega na tym, że czas kompilacji w porównaniu z uruchomieniem oraz w kodzie i poza kodem.
HDave
1

Używam obu. Przeważnie XML, ale kiedy mam kilka ziaren, które dziedziczą po wspólnej klasie i mają wspólne właściwości, używam do nich adnotacji w nadklasie, więc nie muszę ustawiać tych samych właściwości dla każdego ziarna. Ponieważ jestem trochę maniakiem kontroli, używam @Resource (name = "referBean") zamiast po prostu automatycznego okablowania (i oszczędzam sobie wielu kłopotów, jeśli kiedykolwiek będę potrzebował kolejnego ziarna tej samej klasy, co pierwotna wskazana fasola) .

Chochos
źródło
1

Z mojego doświadczenia wynika, że ​​konfiguracja adnotacji ma kilka zalet i wad:

  • Jeśli chodzi o konfigurację JPA, ponieważ jest ona wykonywana raz i zwykle nie są zmieniane dość często, wolę trzymać się konfiguracji adnotacji. Może być obawa o możliwość obejrzenia większego obrazu konfiguracji - w tym przypadku korzystam z diagramów MSQLWorkbench.
  • Konfiguracja XML jest bardzo dobra, aby uzyskać większy obraz aplikacji, ale może być kłopotliwe znalezienie niektórych błędów do czasu uruchomienia. W tym przypadku adnotacja Spring @Configuration wydaje się lepszym wyborem, ponieważ pozwala zobaczyć również większy obraz, a także pozwala sprawdzić poprawność konfiguracji w czasie kompilacji.
  • Jeśli chodzi o konfigurację Springa, wolę połączyć oba podejścia: użyj adnotacji @Configuration z interfejsami usług i zapytań oraz konfiguracją xml dla danych źródłowych i konfiguracji sprężyn, takich jak kontekst: skanowanie komponentów pakiet podstawowy = "..."
  • Jednak konfiguracja XML ogranicza adnotacje java, jeśli chodzi o konfigurację przepływu (Spring Web Flow lub Lexaden Web Flow), ponieważ niezwykle ważne jest, aby zobaczyć szerszy obraz całego procesu biznesowego. Wdrożenie go z podejściem do adnotacji wydaje się niewygodne.

Wolę połączyć oba podejścia - adnotacje Java i niezbędne minimum XML, które minimalizuje piekło konfiguracji.

Denis Skarbichev
źródło
1

W przypadku Spring Framework podoba mi się pomysł użycia adnotacji @Component i ustawienia opcji „skanowanie komponentów”, tak aby Spring mógł znaleźć moje ziarna java, tak że nie muszę definiować wszystkich moich ziaren w XML ani w JavaConfig. Na przykład w przypadku bezstanowych, singletonowych ziaren java, które muszą być po prostu połączone z innymi klasami (najlepiej przez interfejs), to podejście działa bardzo dobrze. Ogólnie rzecz biorąc, w przypadku Spring Bean w większości odeszłam od Spring XML DSL do definiowania komponentów bean, a teraz preferuję użycie JavaConfig i Spring Annotations, ponieważ otrzymujemy trochę czasu kompilacji konfiguracji i wsparcie dla refaktoryzacji, którego nie ma. Otrzymać z konfiguracją Spring XML. W pewnych rzadkich przypadkach mieszam te dwa elementy, gdy stwierdziłem, że JavaConfig / Annotations nie może zrobić tego, co jest dostępne przy użyciu konfiguracji XML.

W przypadku Hibernate ORM (jeszcze nie korzystałem z JPA) nadal wolę pliki mapowania XML, ponieważ adnotacje w klasach modelu domeny w pewnym stopniu naruszają czystą architekturę, która jest warstwowym stylem architektonicznym, który przyjąłem w ciągu ostatnich kilku lat. Naruszenie ma miejsce, ponieważ wymaga, aby warstwa rdzenia była zależna od elementów związanych z trwałością, takich jak biblioteki Hibernate lub JPA, i sprawia, że ​​POJO modelu domeny są nieco mniej trwałe w ignorancji. W rzeczywistości warstwa rdzenia nie powinna w ogóle zależeć od żadnej innej infrastruktury.

Jeśli jednak Czysta Architektura nie jest twoją "filiżanką herbaty", to widzę zdecydowanie zalety (takie jak wygoda i łatwość utrzymania) używania adnotacji Hibernate / JPA w klasach modelu domeny w porównaniu z oddzielnymi plikami mapowania XML.

bielsza
źródło