Je suis curieux de savoir comment l'injection de ressort gère les méthodes d'appel avec l'annotation @Bean
. Si je mets une annotation @Bean
Sur une méthode et retourne une instance, je comprends que cela indique à spring de créer un bean en appelant la méthode et en récupérant l'instance renvoyée. Cependant, ce bean doit parfois être utilisé pour câbler d'autres beans ou pour configurer un autre code. La manière habituelle de procéder consiste à appeler la méthode annotée @Bean
Pour obtenir une instance. Ma question est la suivante: pourquoi cela ne cause-t-il pas de multiples occurrences du bean?
Par exemple, voir le code ci-dessous (tiré d'une autre question). La méthode entryPoint()
est annotée avec @Bean
. J'imagine donc que spring va créer une nouvelle instance de BasicAuthenticationEntryPoint
sous la forme d'un haricot. Ensuite, nous appelons à nouveau entryPoint()
dans le bloc de configuration, mais il semble que entryPoint()
renvoie l'instance de bean et n'est pas appelée plusieurs fois (j'ai essayé de consigner et je n'ai enregistré qu'un seul journal entrée). Potentiellement, nous pourrions appeler entryPoint()
plusieurs fois dans d'autres parties de la configuration, et nous obtiendrions toujours la même instance. Est-ce que ma compréhension de ceci est correcte? Spring fait-il une réécriture magique des méthodes annotées avec @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();
}
Oui, le printemps en fait magie. Vérifiez le Spring Docs :
C’est là que la magie entre: Tout
@Configuration
Les classes sont sous-classées au démarrage avec CGLIB . Dans la sous-classe, la méthode enfant vérifie d'abord le conteneur pour tous les beans mis en cache (scoped) avant d'appeler la méthode parent et de créer une nouvelle instance.
Cela signifie que les appels à @Bean
Les méthodes sont soumises à un proxy via CGLIB et, par conséquent, la version en cache du bean est renvoyée (une nouvelle n'est pas créée).
La portée par défaut de @Bean
s est SINGLETON
, si vous spécifiez une autre portée telle que PROTOTYPE
, l'appel sera transmis à la méthode d'origine.
Notez que ceci est non valide pour les méthodes statiques . Selon les documents de printemps:
Appels à static
@Bean
Les méthodes ne sont jamais interceptées par le conteneur, pas même au sein de@Configuration
classes (comme décrit précédemment dans cette section), en raison de limitations techniques: le sous-classement CGLIB ne peut remplacer que les méthodes non statiques. En conséquence, un appel direct à un autre@Bean
La méthode a la sémantique standard Java), ce qui a pour effet de renvoyer une instance indépendante directement à partir de la méthode factory.