Studiuję do uzyskania certyfikatu Spring Core i mam pewne wątpliwości co do tego, jak Spring radzi sobie z cyklem życia ziaren, aw szczególności z postprocesorem fasoli .
Więc mam taki schemat:
Jest dla mnie całkiem jasne, co to oznacza:
W fazie ładowania definicji komponentów bean wykonywane są następujące kroki :
W @Configuration zajęcia są przetwarzane i / lub @Components są skanowane pod kątem i / lub pliki XML są analizowane.
Definicje Bean dodane do BeanFactory (każda zindeksowana pod swoim identyfikatorem)
Wywołana specjalna fasola BeanFactoryPostProcessor może zmodyfikować definicję dowolnego komponentu bean (na przykład w celu zastąpienia wartości zastępczej właściwości).
Następnie w fazie tworzenia fasoli mają miejsce następujące kroki :
Każda fasola jest domyślnie tworzona z niecierpliwością (tworzona we właściwej kolejności z wstrzykniętymi zależnościami).
Po wstrzyknięciu zależności każde ziarno przechodzi przez fazę przetwarzania końcowego, w której może nastąpić dalsza konfiguracja i inicjalizacja.
Po przetworzeniu końcowym ziarno jest w pełni zainicjowane i gotowe do użycia (śledzone przez jego identyfikator, aż do zniszczenia kontekstu)
Ok, jest to dla mnie całkiem jasne i wiem też, że istnieją dwa typy postprocesorów fasoli :
Inicjalizatory: Inicjalizacja fasoli jeśli polecił (tj @PostConstruct).
i Cała reszta: pozwala na dodatkową konfigurację i może działać przed lub po kroku inicjalizacji
I publikuję ten slajd:
Więc jest dla mnie bardzo jasne, co inicjalizatory bean postprocesorów (są to metody z adnotacją @PostContruct i które są automatycznie wywoływane natychmiast po metodach ustawiających (czyli po wstrzyknięciu zależności) i wiem, że mogę użyć do wykonać partię inicjalizacyjną (zapełnij pamięć podręczną, jak w poprzednim przykładzie).
Ale co dokładnie reprezentuje drugi postprocesor fasoli? Co mamy na myśli, gdy mówimy, że te kroki są wykonywane przed lub po fazie inicjalizacji ?
Więc moje ziarna są tworzone, a ich zależności są wstrzykiwane, więc faza inicjalizacji jest zakończona (przez wykonanie metody z adnotacjami @PostContruct ). Co mamy na myśli, mówiąc, że postprocesor Bean jest używany przed fazą inicjalizacji? Oznacza to, że dzieje się to przed wykonaniem metody z adnotacjami @PostContruct ? Czy to oznacza, że może się to zdarzyć przed wstrzyknięciem zależności (przed wywołaniem metod ustawiających)?
A co dokładnie mamy na myśli, gdy mówimy, że jest to wykonywane po kroku inicjalizacji . Oznacza to, że dzieje się to po wykonaniu metody z adnotacjami @PostContruct , czy co?
Mogę łatwo zrozumieć, dlaczego potrzebuję metody z adnotacjami @PostContruct , ale nie mogę znaleźć typowego przykładu innego rodzaju postprocesora fasoli, czy możesz mi pokazać typowy przykład kiedy są używane?
źródło
Odpowiedzi:
Dokument Spring wyjaśnia BPP w sekcji Dostosowywanie ziaren przy użyciu BeanPostProcessor . Ziarna BPP to specjalny rodzaj ziaren, które powstają przed innymi ziarnami i wchodzą w interakcję z nowo powstałymi ziarnami. Dzięki tej konstrukcji Spring umożliwia podłączenie i dostosowanie zachowania cyklu życia po prostu przez zaimplementowanie
BeanPostProcessor
siebie.Posiadanie niestandardowego BPP, takiego jak
public class CustomBeanPostProcessor implements BeanPostProcessor { public CustomBeanPostProcessor() { System.out.println("0. Spring calls constructor"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println(bean.getClass() + " " + beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println(bean.getClass() + " " + beanName); return bean; } }
zostanie wywołana i wydrukuje klasę i nazwę fasoli dla każdego utworzonego ziarna.
Aby dowiedzieć się, jak metoda pasuje do cyklu życia fasoli i kiedy dokładnie metoda jest wywoływana, sprawdź dokumentację
Ważne jest również to
Jeśli chodzi o związek z
@PostConstruct
uwagą, ta adnotacja jest wygodnym sposobem zadeklarowaniapostProcessAfterInitialization
metody, a Spring zdaje sobie z tego sprawę, kiedy albo rejestrujesz się,CommonAnnotationBeanPostProcessor
albo określasz<context:annotation-config />
plik konfiguracyjny w beanie. To, czy@PostConstruct
metoda zostanie wykonana przed, czy po jakiejkolwiek innej,postProcessAfterInitialization
zależy odorder
właściwościźródło
Typowym przykładem postprocesora fasoli jest sytuacja, gdy chcesz zawinąć oryginalny bean w instancję proxy, np. Podczas korzystania z
@Transactional
adnotacji.Postprocesor bean otrzyma oryginalną instancję fasoli, może wywołać dowolne metody w miejscu docelowym, ale może również zwrócić rzeczywistą instancję fasoli, która powinna być powiązana w kontekście aplikacji, co oznacza, że może faktycznie zwrócić dowolną obiekt, którego chce. Typowym scenariuszem, w którym jest to przydatne, jest sytuacja, gdy postprocesor fasoli opakowuje obiekt docelowy w instancję proxy. Wszystkie wywołania komponentu bean związanego w kontekście aplikacji będą przechodzić przez proxy, a następnie proxy będzie mogło wykonać magię przed i / lub po wywołaniach na docelowym beanie, np. AOP lub zarządzanie transakcjami.
źródło
Różnica polega na tym,
BeanPostProcessor
że podłączy się do inicjalizacji kontekstu, a następnie wywołapostProcessBeforeInitialization
ipostProcessAfterInitialization
dla wszystkich zdefiniowanych komponentów bean.Ale
@PostConstruct
jest używany tylko dla określonej klasy, którą chcesz dostosować tworzenie bean po konstruktorze lub metodzie set.źródło