2010-04-17 23 views

Odpowiedz

14

Nie rób ich final. Jeśli użyjesz dowolnego AOP (w tym obsługi transakcji) na konkretnych klasach, wiosna użyje CGLIB do dynamicznego rozszerzenia klasy w celu utworzenia proxy. A wymaganie, aby CGLIB działał, to posiadanie klas non-final. W przeciwnym razie zostanie zgłoszony wyjątek.

+0

Dobra odpowiedź. Więc klasy DAO mogą być "ostateczne"? Zazwyczaj nie są transakcyjne. – fastcodejava

+2

Cóż, wtedy _ może, ale bądź ostrożny z tym również. Możesz w pewnym momencie dodać trochę AOP do nich. – Bozho

+1

To jest wadą tych narzędzi, aby nie móc instrumentować "końcowych" klas, które są niezbędne do prawidłowego projektowania OO (patrz, na przykład, książka "Practical API Design" - lub nawet książka GoF). Tam * są * sposoby na końcowe klasy instrumentów; narzędzia takie jak CGLIB są przestarzałe. –

4

Wiosna stworzy JDK dynamicznego proxy zamiast pełnomocnictwa CGLIB jeżeli spełnione są następujące warunki:

  1. aop: config ma proxy-target-klasy ustawiona na false
  2. Wszelkie inne konfiguracje przestrzeni nazw (np tx : transakcja zarządzanie), mają również proxy-target-klasy ustawiona na false
  3. twoja klasa implementuje interfejs

Jeśli wszystkie trzy są prawdziwe, to można zadeklarować final class. (Możesz nawet uczynić pakiet class-private i konstruktor prywatny, jeśli chcesz, Spring będzie mógł go utworzyć).

W przeciwnym razie Spring utworzy proxy CGLIB. Nadal możesz zadeklarować ostateczną klasę (zakładając, że nie jest ona ozdobiona @Repository i nie masz zadeklarowanej wartości PersistenceExceptionPostBeanProcessor), jeśli w komponencie bean nie ma żadnych publicznych metod. Gdy masz już jedną publiczną metodę, nie możesz zadeklarować finału klasy z proxy CBLIB. (Uwaga: podczas pośredniczenia przez CGLIB musisz mieć co najmniej konstruktor prywatny, bez argumentów).

Kiedy powyższe informacje są przydatne? Załóżmy, że masz interfejs usługi (wszystkie usługi powinny ogólnie mieć interfejsy) z komponentem implementacji, który jest pakietem prywatnym. Usługa korzysta z dynamicznego proxy proxy JDK. Tak więc może być ostateczna i niewidoczna poza pakietem, przenikając mniej szczegółów dotyczących implementacji. Powiedzmy, że usługa wymaga obiektu dostępu do danych. Jeśli żadna inna usługa nie korzysta z tego DAO, dlaczego ta metoda lub jakakolwiek z jej metod jest publiczna? Jeśli wszystkie metody w DAO są pakietowo prywatne, implementacja usługi może nadal wiązać DAO i używać jej metod. Spoza pakietu osoby dzwoniące widzą tylko interfejs (coś dobrego) i wszelkie typy używane w sygnaturze interfejsu.

Wreszcie (gra słów nie jest przeznaczona), w ostatniej klasie, kiedy tylko możesz. Dziedziczenie z betonu często mylnie przedstawia nadużycie (patrz: fragile base problem). Klasy końcowe umożliwiają również optymalizacje kompilacji.