Injektion af forårbønner i ikke-administrerede objekter

1. Drivkræfter

I en forårsprogram er det meget almindeligt at injicere en bønne i en anden bønne. Imidlertid nogle gange det er ønskeligt at injicere en bønne i en almindelig genstand. For eksempel vil vi muligvis hente referencer til tjenester fra et objektobjekt.

Heldigvis er det ikke så svært at nå det, som det kan se ud. De følgende afsnit præsenterer, hvordan man gør det bruger @Configurable kommentar og en AspectJ-væver.

2. Den @Configurable Kommentar

Denne kommentar tillader forekomster af den dekorerede klasse at have referencer til Spring beans.

2.1. Definition og registrering af en Spring Bean

Før du dækker @Configurable kommentar, lad os oprette en definition af Spring Bean:

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

Denne klasse er dekoreret med @Service kommentar derfor kan det registreres med en Spring-kontekst via komponentscanning.

Her er en simpel konfigurationsklasse, der muliggør denne mekanisme:

@ComponentScan offentlig klasse AspectJConfig {}

2.2. Ved brug af @Configurable

I sin enkleste form, vi kan bruge @Configurable uden noget element:

@Configurable public class PersonObject {private int id; privat strengnavn; offentlig PersonObject (strengnavn) {this.name = navn; } // getters og anden kode vist i næste underafsnit}

Det @Configurable kommentar, i dette tilfælde markerer PersonObject klasse som kvalificeret til fjederdrevet konfiguration.

2.3. Injektion af en springbønne i et ikke-administreret objekt

Vi kan injicere IdService ind i PersonObject, ligesom vi ville gøre det i enhver forårsbønne:

@Configurable public class PersonObject {@Autowired private IdService idService; // felter, konstruktør og getters - vist i det forrige underafsnit ugyldigt generereId () {dette.id = idService.generateId (); }}

En kommentar er dog kun nyttig, hvis den genkendes og behandles af en handler. Det er her, AspectJ-væver spiller ind. Specifikt det AnnotationBeanConfigurerAspect vil handle på tilstedeværelsen af @Konfigurerbar og udfører den nødvendige behandling.

3. Aktivering af AspectJ-vævning

3.1. Plugin-erklæring

For at aktivere AspectJ-vævning har vi først brug for AspectJ Maven-pluginet:

 org.codehaus.mojo aspectj-maven-plugin 1.11 

Og det kræver en vis yderligere konfiguration:

 1.8 ignorere org.springframework fjederaspekter 

Det første nødvendige element er overholdelseNiveau. En værdi af 1.8 indstiller både kilde- og mål-JDK-versionerne til 1.8. Hvis det ikke er angivet eksplicit, ville kildeversionen være 1.3, og målet ville være 1.1. Disse værdier er naturligvis forældede og ikke nok til en moderne Java-applikation.

For at injicere en bønne i et ikke-administreret objekt, skal vi stole på AnnotationBeanConfigurerAspect klasse i foråret-aspekter.jar. Da dette er et forud kompileret aspekt, ville vi have brug for det tilføj den indeholdende artefakt til plugin-konfigurationen.

Bemærk, at en sådan henvist artefakt skal eksistere som en afhængighed i projektet:

 org.springframework fjederaspekter 5.2.7.RELEASE 

Vi kan finde den nyeste version af foråret-aspekter på Maven Central.

3.2. Plugin-udførelse

For at instruere pluginet om at væve alle relevante klasser har vi brug for dette henrettelser konfiguration:

   udarbejde 

Varsel plugin'et udarbejde mål binder som standard til kompileringscyklusfasen.

3.2. Bønnekonfiguration

Det sidste trin for at aktivere AspectJ-vævning er at tilføje @EnableSpringConfigured til konfigurationsklassen:

@ComponentScan @EnableSpringConfigured offentlig klasse AspectJConfig {}

Den ekstra kommentar konfigureres AnnotationBeanConfigurerAspect, som igen registreres PersonObject forekomster med en Spring IoC-container.

4. Testning

Lad os nu kontrollere, at IdService bønne er blevet injiceret med succes i en 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. Injektion af en bønne i en JPA-enhed

Fra Spring Containers synspunkt er en enhed intet andet end et almindeligt objekt. Som sådan er der ikke noget særligt ved at injicere en forårsbønne i en JPA-enhed.

Da injektion i JPA-enheder er en typisk brugssag, lad os dog dække det mere detaljeret.

5.1. Enhedsklasse

Lad os starte med enhedsklassens skelet:

@Entity @Configurable (preConstruction = true) offentlig klasse PersonEntity {@Id privat int id; privat strengnavn; public PersonEntity () {} // anden kode - vises i næste underafsnit}

Læg mærke til prækonstruktion element i @Konfigurerbar kommentar: det gør det muligt for os at injicere en afhængighed i objektet, før det er fuldt konstrueret.

5.2. Serviceinjektion

Nu kan vi injicere IdService ind i PersonEnhed, svarende til hvad vi gjorde med PersonObject:

// annotationer public class PersonEntity {@Autowired @Transient private IdService idService; // felter og ikke-arg konstruktør offentlig PersonEntity (strengnavn) {id = idService.generateId (); dette.navn = navn; } // getters}

Det @Transient annotering bruges til at fortælle JPA det idService er et felt, der ikke skal vedholdes.

5.3. Testmetodeopdatering

Endelig kan vi opdatere testmetoden for at indikere, at tjenesten kan injiceres i enheden:

@Test offentlig ugyldighed givenUnmanagedObjects_whenInjectingIdService_thenIdValueIsCorrectlySet () {// eksisterende udsagn PersonEntity personEntity = ny PersonEntity ("Baeldung"); assertEquals (2, personEntity.getId ()); assertEquals ("Baeldung", personEntity.getName ()); }

6. forbehold

Selvom det er praktisk at få adgang til fjederkomponenter fra et ikke-administreret objekt, er det ofte ikke en god praksis at gøre det.

Problemet er, at ikke-styrede objekter, herunder enheder, normalt er en del af domænemodellen. Disse objekter skal kun medføre data for at kunne genbruges på tværs af forskellige tjenester.

Injektion af bønner i sådanne genstande kan binde komponenter og genstande sammen, hvilket gør det sværere at vedligeholde og forbedre applikationen.

7. Konklusion

Denne vejledning har gennemgået processen med at injicere en springbønne i et ikke-administreret objekt. Det nævnte også et designproblem forbundet med indsprøjtning af afhængighed i objekter.

Implementeringskoden kan findes på GitHub.


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