Injisere vårbønner i ubehandlede objekter

1. Drivkrefter

I en vårapplikasjon er det veldig vanlig å injisere en bønne i en annen bønne. Imidlertid noen ganger det er ønskelig å injisere en bønne i en vanlig gjenstand. For eksempel kan det være lurt å skaffe referanser til tjenester fra et enhetsobjekt.

Heldigvis er det ikke så vanskelig som det kan se ut å oppnå det. De følgende avsnittene vil presentere hvordan du gjør det bruker @Konfigurerbar kommentar og en AspectJ-vever.

2. Den @Konfigurerbar Kommentar

Denne kommentaren lar forekomster av den dekorerte klassen holde referanser til vårbønner.

2.1. Definere og registrere en vårbønne

Før du dekker @Konfigurerbar kommentar, la oss sette opp en definisjon av vårbønne:

@Service offentlig klasse IdService {privat statisk antall teller; int createId () {return ++ count; }}

Denne klassen er dekorert med @Service kommentar; dermed kan den registreres med en vårkontekst via komponentskanning.

Her er en enkel konfigurasjonsklasse som muliggjør den mekanismen:

@ComponentScan offentlig klasse AspectJConfig {}

2.2. Ved hjelp av @Konfigurerbar

I sin enkleste form, Vi kan bruke @Konfigurerbar uten noe element:

@Configurable public class PersonObject {private int id; privat strengnavn; offentlig PersonObject (strengnavn) {this.name = name; } // getters og annen kode vist i neste underavsnitt}

De @Konfigurerbar kommentar, i dette tilfellet, markerer PersonObject klasse som kvalifisert for vårdrevet konfigurasjon.

2.3. Injisere en vårbønne i et ikke-administrert objekt

Vi kan injisere IdService inn i PersonObject, akkurat som vi ville gjort i alle vårbønner:

@Configurable public class PersonObject {@Autowired private IdService idService; // felt, konstruktør og getters - vist i forrige underavsnitt void generereId () {this.id = idService.generateId (); }}

En kommentar er imidlertid bare nyttig hvis den blir gjenkjent og behandlet av en behandler. Det er her AspectJ-vever spiller inn. Nærmere bestemt, de AnnotationBeanConfigurerAspect vil handle på nærvær av @Konfigurerbar og utfører nødvendig behandling.

3. Aktivere AspectJ Weaving

3.1. Plugin-erklæring

For å aktivere AspectJ-veving trenger vi først AspectJ Maven-plugin:

 org.codehaus.mojo aspectj-maven-plugin 1.11 

Og det krever litt ekstra konfigurasjon:

 1.8 ignorere org.springframework våraspekter 

Det første nødvendige elementet er samsvar Nivå. En verdi av 1.8 setter både kilde- og mål-JDK-versjoner til 1.8. Hvis ikke angitt eksplisitt, ville kildeversjonen være 1.3 og målet ville være 1.1. Disse verdiene er åpenbart utdaterte og ikke nok for et moderne Java-program.

For å injisere en bønne i et ikke-administrert objekt, må vi stole på AnnotationBeanConfigurerAspect klasse gitt i vår-aspekter.jar. Siden dette er et forhåndskompilert aspekt, vil vi trenge det legg til artefakten som inneholder plugin-konfigurasjonen.

Merk at en slik referert gjenstand må eksistere som en avhengighet i prosjektet:

 org.springframework våraspekter 5.2.7.RELEASE 

Vi finner den nyeste versjonen av våraspekter på Maven Central.

3.2. Plugin-gjennomføring

For å instruere programtillegget om å veve alle relevante klasser, trenger vi dette henrettelser konfigurasjon:

   kompilere 

Legge merke til plugin-en kompilere mål binder seg til kompileringssyklusfasen som standard.

3.2. Bønnekonfigurasjon

Det siste trinnet for å aktivere AspectJ-veving er å legge til @EnableSpringConfigured til konfigurasjonsklassen:

@ComponentScan @EnableSpringConfigured offentlig klasse AspectJConfig {}

Den ekstra kommentaren konfigureres AnnotationBeanConfigurerAspect, som igjen registrerer seg PersonObject forekomster med en Spring IoC-container.

4. Testing

La oss nå kontrollere at IdService bønne har blitt injisert med suksess PersonObject:

@RunWith (SpringRunner.class) @ContextConfiguration (classes = AspectJConfig.class) public class PersonUnitTest {@Test public void givenUnmanagedObjects_whenInjectingIdService_thenIdValueIsCorrectlySet () {PersonObject personObject; new Personbject; personObject.generateId (); assertEquals (1, personObject.getId ()); assertEquals ("Baeldung", personObject.getName ()); }}

5. Injisere en bønne i en JPA-enhet

Fra vårcontainerens synspunkt er en enhet ikke annet enn et vanlig objekt. Som sådan er det ikke noe spesielt med å injisere en vårbønne i en JPA-enhet.

Men siden injeksjon i JPA-enheter er en typisk brukssak, la oss dekke det nærmere.

5.1. Enhetsklasse

La oss starte med enhetsklassens skjelett:

@Entity @Configurable (preConstruction = true) offentlig klasse PersonEntity {@Id privat int id; privat strengnavn; public PersonEntity () {} // annen kode - vises i neste underavsnitt}

Legg merke til preConstruction element i @Konfigurerbar kommentar: det gjør det mulig for oss å injisere en avhengighet i objektet før det er fullstendig konstruert.

5.2. Serviceinjeksjon

Nå kan vi injisere IdService inn i PersonEntity, lik det vi gjorde med PersonObject:

// merknader offentlig klasse PersonEntity {@Autowired @Transient private IdService idService; // felt og no-arg konstruktør offentlig PersonEntity (strengnavn) {id = idService.generateId (); this.name = navn; } // getters}

De @Flyktig kommentar brukes til å fortelle JPA det idService er et felt som ikke skal vedvares.

5.3. Testmetodeoppdatering

Til slutt kan vi oppdatere testmetoden for å indikere at tjenesten kan injiseres i enheten:

@Test public void givenUnmanagedObjects_whenInjectingIdService_thenIdValueIsCorrectlySet () {// eksisterende utsagn PersonEntity personEntity = new PersonEntity ("Baeldung"); assertEquals (2, personEntity.getId ()); assertEquals ("Baeldung", personEntity.getName ()); }

6. forbehold

Selv om det er praktisk å få tilgang til fjærkomponenter fra et ikke-administrert objekt, er det ofte ikke god praksis å gjøre det.

Problemet er at ikke-administrerte objekter, inkludert enheter, vanligvis er en del av domenemodellen. Disse objektene skal bare ha data for å være gjenbrukbare på tvers av forskjellige tjenester.

Å injisere bønner i slike gjenstander kan knytte komponenter og gjenstander sammen, noe som gjør det vanskeligere å vedlikeholde og forbedre applikasjonen.

7. Konklusjon

Denne opplæringen har gått gjennom prosessen med å injisere en vårbønne i et ikke-administrert objekt. Det nevnte også et designproblem assosiert med avhengighetsinjeksjon i gjenstander.

Implementeringskoden finner du på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found