Inzicht in getBean () in het voorjaar

1. Inleiding

In deze tutorial gaan we door verschillende varianten van de BeanFactory.getBean () methode.

Simpel gezegd, zoals de naam van de methode ook suggereert, ditis verantwoordelijk voor het ophalen van een boneninstantie uit de Spring-container.

2. Spring Beans Setup

Laten we eerst een paar lente-bonen definiëren om te testen. Er zijn verschillende manieren waarop we bean-definities kunnen geven voor de Spring-container, maar in ons voorbeeld gebruiken we op annotaties gebaseerde Java-configuratie:

@Configuratieklasse AnnotationConfig {@Bean (naam = {"tijger", "kitty"}) @Scope (waarde = "prototype") Tiger getTiger (Stringnaam) {retourneer nieuwe Tiger (naam); } @Bean (name = "lion") Lion getLion () {retourneer nieuwe Lion ("Hardgecodeerde leeuwenaam"); } interface Animal {}} 

We hebben twee bonen gemaakt. Leeuw heeft de standaard singleton scope. Tijger is expliciet ingesteld op prototypebereik. Houd er bovendien rekening mee dat we voor elke boon namen hebben gedefinieerd die we in verdere verzoeken zullen gebruiken.

3. Het getBean () API's

BeanFactory biedt vijf verschillende handtekeningen van de getBean () methode die we gaan onderzoeken in de volgende onderafdelingen.

3.1. Bonen op naam ophalen

Laten we eens kijken hoe we een Leeuw bean-instantie met behulp van zijn naam:

Object lion = context.getBean ("leeuw"); assertEquals (Lion.class, lion.getClass ());

In deze variant geven we een naam op en in ruil daarvoor krijgen we een exemplaar van Voorwerp class als er een bean met de opgegeven naam bestaat in de toepassingscontext. Anders gooien zowel deze als alle andere implementaties NoSuchBeanDefinitionException als het zoeken naar bonen mislukt.

Het grootste nadeel is dat nadat we de boon hebben opgehaald, moeten we deze naar het gewenste type gieten. Dit kan een andere uitzondering opleveren als de geretourneerde boon een ander type heeft dan we hadden verwacht.

Stel dat we proberen een Tijger onder de naam "leeuw". Wanneer we het resultaat casten naar Tijger, het zal een ClassCastException:

assertThrows (ClassCastException.class, () -> {Tiger tiger = (Tiger) context.getBean ("leeuw");});

3.2. Bean ophalen op naam en type

Hier moeten we zowel de naam als het type van de aangevraagde bean specificeren:

Lion lion = context.getBean ("leeuw", Lion.class);

In vergelijking met de vorige methode is deze veiliger omdat we de informatie over niet-overeenkomende typen onmiddellijk krijgen:

assertThrows (BeanNotOfRequiredTypeException.class, () -> context.getBean ("leeuw", Tiger.class)); }

3.3. Bonen op type ophalen

Met de derde variant van getBean (), het is voldoende om alleen het bonentype te specificeren:

Lion lion = context.getBean (Lion.class);

In dit geval moeten we besteed speciale aandacht aan een mogelijk dubbelzinnige uitkomst:

assertThrows (NoUniqueBeanDefinitionException.class, () -> context.getBean (Animal.class)); }

In het bovenstaande voorbeeld, omdat beide Leeuw en Tijger implementeer het Dier interface, alleen het specificeren van het type is niet voldoende om het resultaat ondubbelzinnig te bepalen. Daarom krijgen we een NoUniqueBeanDefinitionException.

3.4. Bean ophalen op naam met constructorparameters

Naast de bean-naam kunnen we ook constructor-parameters doorgeven:

Tijgertijger = (Tijger) context.getBean ("tijger", "Siberische");

Deze methode is een beetje anders omdat deze alleen van toepassing is op bonen met een prototype-scope.

In het geval van eenlingen krijgen we een BeanDefinitionStoreException.

Omdat een prototype bean een nieuw gemaakte instantie retourneert elke keer dat deze wordt aangevraagd vanuit de applicatiecontainer, we kunnen on-the-fly constructorparameters leveren bij het aanroepen getBean ():

Tijgertijger = (Tijger) context.getBean ("tijger", "Siberische"); Tiger secondTiger = (Tiger) context.getBean ("tijger", "Gestreept"); assertEquals ("Siberian", tiger.getName ()); assertEquals ("Striped", secondTiger.getName ());

Zoals we kunnen zien, elk Tijger krijgt een andere naam volgens wat we hebben gespecificeerd als een tweede parameter bij het aanvragen van de bean.

3.5. Bean ophalen op type met constructorparameters

Deze methode is analoog aan de vorige, maar we moeten het type in plaats van de naam als eerste argument doorgeven:

Tiger tiger = context.getBean (Tiger.class, "Shere Khan"); assertEquals ("Shere Khan", tiger.getName ());

Vergelijkbaar met het ophalen van een bean op naam met constructorparameters, deze methode is alleen van toepassing op bonen met een prototype-scope.

4. Gebruiksoverwegingen

Ondanks dat het is gedefinieerd in de BeanFactory interface, de getBean () methode wordt het vaakst benaderd via de ApplicationContext. Typisch, we willen de getBean () methode rechtstreeks in ons programma.

Bonen moeten worden beheerd door de container. Als we er een willen gebruiken, moeten we vertrouwen op afhankelijkheidsinjectie in plaats van een directe oproep naar ApplicationContext.getBean (). Op die manier kunnen we voorkomen dat applicatielogica wordt gemengd met raamwerkgerelateerde details.

5. Conclusie

In deze korte tutorial hebben we alle implementaties van het getBean () methode van de BeanFactory interface en beschreef de voor- en nadelen van elk.

Alle codevoorbeelden die hier worden getoond, zijn beschikbaar op GitHub.


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