Een @Bean-geannoteerde methode aanroepen in Spring Java-configuratie

Ik ben benieuwd hoe Spring Injection omgaat met belmethoden met de @Beanannotatie. Als ik een @Bean-annotatie op een methode plaats en een instantie retourneer, begrijp ik dat dat Spring vertelt om een ​​bean te maken door de methode aan te roepen en de geretourneerde instantie te krijgen. Soms moet die boon echter worden gebruikt om andere bonen te bedraden of een andere code in te stellen. De gebruikelijke manier waarop dit wordt gedaan, is door de geannoteerde methode @Beanaan te roepen om een ​​instantie te krijgen. Mijn vraag is, waarom zorgt dit er niet voor dat er meerdere exemplaren van de boon rondzweven?

Zie bijvoorbeeld de onderstaande code (overgenomen uit een andere vraag). De methode entryPoint()is geannoteerd met @Bean, dus ik kan me voorstellen dat Spring een nieuw exemplaar van BasicAuthenticationEntryPointals een bean zal maken. Vervolgens roepen we entryPoint()opnieuw aan in het configuratieblok, maar het lijkt erop dat entryPoint()de bean-instantie retourneert en niet meerdere keren wordt aangeroepen (ik heb geprobeerd , en kreeg slechts één logboekinvoer). Mogelijk zouden we entryPoint()meerdere keren kunnen aanroepen in andere delen van de configuratie, en we zouden altijd dezelfde instantie krijgen. Klopt mijn begrip hiervan? Herschrijft de lente op magische wijze methoden die zijn geannoteerd met @Bean?

@Bean
public BasicAuthenticationEntryPoint entryPoint() {
    BasicAuthenticationEntryPoint basicAuthEntryPoint = new BasicAuthenticationEntryPoint();
    basicAuthEntryPoint.setRealmName("My Realm");
    return basicAuthEntryPoint;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .exceptionHandling()
            .authenticationEntryPoint(entryPoint())
            .and()
        .authorizeUrls()
            .anyRequest().authenticated()
            .and()
        .httpBasic();       
}

Antwoord 1, autoriteit 100%

Ja, de lente doet wat magie. Controleer de Spring Docs:

Hier komt de magie om de hoek kijken: alle @Configuration-klassen worden bij het opstarten gesubclasseerd met CGLIB. In de subklasse controleert de onderliggende methode de container eerst op in de cache opgeslagen (scoped) bonen voordat deze de bovenliggende methode aanroept en een nieuwe instantie maakt.

Dit betekent dat de aanroepen van @Bean-methoden via CGLIBworden verzonden en daarom wordt de gecachte versie van de bean geretourneerd (er wordt geen nieuwe gemaakt).

Het standaardbereik van @Beans is SINGLETON, als u een ander bereik opgeeft, zoals PROTOTYPE, wordt de aanroep doorgegeven aan de originele methode.

Houd er rekening mee dat dit niet geldig is voor statische methoden. Volgens de voorjaarsdocumenten:

Aanroepen naar statische @Bean-methoden worden nooit onderschept door de container, zelfs niet binnen @Configuration-klassen (zoals eerder beschreven in deze sectie), vanwege technische beperkingen: CGLIB-subklassen kunnen alleen niet-statische methoden overschrijven. Als gevolg hiervan heeft een directe aanroep naar een andere @Bean-methode standaard Java-semantiek, wat resulteert in een onafhankelijke instantie die rechtstreeks vanuit de fabrieksmethode zelf wordt geretourneerd.

Other episodes