Ubrizgavanje proljetnog graha u neupravljane predmete
1. Pogonske snage
U proljetnoj aplikaciji ubrizgavanje jednog graha u drugi grah vrlo je često. Međutim, ponekad poželjno je ubrizgati grah u obični predmet. Na primjer, možda ćemo htjeti dobiti reference na usluge unutar entiteta.
Srećom, postići to nije tako teško kako bi moglo izgledati. Sljedeći odjeljci predstavit će kako to učiniti koristiti @Configurable anotacija i tkač AspectJ.
2. The @Configurable Bilješka
Ova bilješka omogućuje primjercima ukrašene klase da sadrže reference na proljetni grah.
2.1. Definiranje i registracija proljetnog graha
Prije pokrivanja @Configurable napomena, postavimo definiciju proljetnog graha:
@Service javna klasa IdService {private static int count; int generirajId () {return ++ count; }}
Ovaj razred ukrašen je @Servis bilješka; stoga se može registrirati u Spring kontekstu putem skeniranja komponenata.
Evo jednostavne klase konfiguracije koja omogućuje taj mehanizam:
@ComponentScan javna klasa AspectJConfig {}
2.2. Koristeći @Configurable
U svom najjednostavnijem obliku, možemo koristiti @Configurable bez ikakvog elementa:
@ Konfigurabilna javna klasa PersonObject {private int id; privatni naziv niza; javni PersonObject (ime niza) {this.name = name; } // getteri i drugi kod prikazan u sljedećem pododjeljku}
The @Configurable napomena, u ovom slučaju, označava PersonObject klasa kao prihvatljiva za konfiguraciju pogonjenu oprugom.
2.3. Ubrizgavanje proljetnog graha u neupravljani objekt
Možemo ubrizgati IdService u PersonObject, baš kao i u bilo kojem proljetnom grahu:
@ Konfigurabilna javna klasa PersonObject {@Autowired private IdService idService; // polja, konstruktor i getteri - prikazano u prethodnom pododjeljku void generiraj id () {this.id = idService.generateId (); }}
Međutim, napomena je korisna samo ako je rukovatelj prepozna i obradi. Tu nastupa tkač AspectJ. Posebno, the AnnotationBeanConfigurerAspect djelovat će na prisutnost @Configurable i radi potrebnu obradu.
3. Omogućavanje tkanja AspectJ
3.1. Izjava o dodatku
Da bismo omogućili tkanje AspectJ, prvo nam treba dodatak AspectJ Maven:
org.codehaus.mojo aspektj-maven-plugin 1.11
I potrebna je dodatna konfiguracija:
1.8 zanemariti org.springframework proljeće-aspekte
Prvi potreban element je usklađenostNivo. Vrijednost od 1.8 postavlja i izvornu i ciljanu verziju JDK na 1,8. Ako se eksplicitno ne postavi, izvorna verzija bila bi 1.3, a ciljna 1.1. Te su vrijednosti očito zastarjele i nisu dovoljne za modernu Java aplikaciju.
Da bismo ubrizgali grah u neupravljani objekt, moramo se osloniti na AnnotationBeanConfigurerAspect klasa predviđena u proljetni aspekti.jar. Budući da je ovo unaprijed sastavljeni aspekt, morali bismo dodajte sadržani artefakt u konfiguraciju dodatka.
Imajte na umu da takav referencirani artefakt mora postojati kao ovisnost u projektu:
org.springframework opruga-aspekti 5.2.7.OBUSTAŽENJE
Možemo pronaći najnoviju verziju proljetni aspekti na Maven Central.
3.2. Izvršenje dodatka
Da bismo uputili dodatak da tka sve relevantne razrede, trebamo ovo pogubljenja konfiguracija:
sastaviti
Obavijest dodatak sastaviti Cilj se prema zadanim postavkama veže za fazu životnog ciklusa kompajliranja.
3.2. Konfiguracija graha
Posljednji korak za omogućavanje tkanja AspectJ je dodati @EnableSpringConfigured u konfiguracijsku klasu:
@ComponentScan @EnableSpringConfigured javna klasa AspectJConfig {}
Dodatna napomena se konfigurira AnnotationBeanConfigurerAspect, koja se pak registrira PersonObject primjerke s Spring IoC spremnikom.
4. Ispitivanje
Sada, provjerimo da li IdService grah je uspješno ubrizgan u PersonObject:
@RunWith (SpringRunner.class) @ContextConfiguration (classes = AspectJConfig.class) javna klasa PersonUnitTest {@Test javna praznina givenUnmanagedObjects_whenInjectingIdService_thenIdValueIsCorrectSet () {PersonObject personBobonbject = novi personObject.generateId (); assertEquals (1, personObject.getId ()); assertEquals ("Baeldung", personObject.getName ()); }}
5. Ubrizgavanje graha u JPA entitet
S gledišta Spring kontejnera, entitet nije ništa drugo nego običan objekt. Kao takav, nema ništa posebno u ubrizgavanju proljetnog graha u JPA entitet.
Međutim, budući da je ubrizgavanje u JPA entitete tipičan slučaj upotrebe, pokrenimo ga detaljnije.
5.1. Entitetna klasa
Krenimo od kostura klase entiteta:
@Entity @Configurable (preConstruction = true) javna klasa PersonEntity {@Id private int id; privatni naziv niza; javni PersonEntity () {} // drugi kôd - prikazan u sljedećem pododjeljku}
Primijetite predkonstrukcija element u @Configurable napomena: omogućuje nam ubrizgavanje ovisnosti u objekt prije nego što je u potpunosti izgrađen.
5.2. Injekcija usluge
Sada možemo ubrizgati IdService u PersonEntity, slično onome što smo radili PersonObject:
// napomene javna klasa PersonEntity {@Autowired @Transient private IdService idService; // polja i konstruktor no-arg public PersonEntity (naziv niza) {id = idService.generateId (); this.name = ime; } // dobivači}
The @Prijelazno anotacija se koristi da se kaže JPA idService je polje koje se ne smije ustrajati.
5.3. Ažuriranje metode ispitivanja
Napokon, možemo ažurirati metodu ispitivanja kako bismo naznačili da se usluga može ubrizgati u entitet:
@Test javna praznina givenUnmanagedObjects_whenInjectingIdService_thenIdValueIsCorrectSet () {// postojeće izjave PersonEntity personEntity = nova PersonEntity ("Baeldung"); assertEquals (2, personEntity.getId ()); assertEquals ("Baeldung", personEntity.getName ()); }
6. Upozorenja
Iako je prikladno pristupiti komponentama Spring iz neupravljanog objekta, često to nije dobra praksa.
Problem je u tome što su neupravljeni objekti, uključujući entitete, obično dio modela domene. Ti bi objekti trebali prenositi podatke samo da bi se mogli ponovno koristiti u različitim uslugama.
Ubrizgavanje graha u takve predmete moglo bi povezati komponente i predmete, što otežava održavanje i poboljšanje primjene.
7. Zaključak
Ovaj je vodič prošao kroz postupak ubrizgavanja proljetnog graha u neupravljani objekt. Također je spomenuto pitanje dizajna povezano s ubrizgavanjem ovisnosti u objekte.
Kôd za implementaciju može se naći na GitHub-u.