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.