java - mvc - que es un bean en spring
Llamar a un método anotado @Bean en la configuración de Spring Java (1)
Sí, Spring hace algo de magia . Consulta los documentos de primavera :
Aquí es donde entra la magia: todas
@Configuration
clases de@Configuration
se subclasifican en el momento de inicio con CGLIB . En la subclase, el método secundario comprueba primero el contenedor en busca de beans almacenados en caché (con ámbito) antes de llamar al método principal y crea una nueva instancia.
Esto significa que las llamadas a los métodos
@Bean
se
CGLIB
mediante
CGLIB
y, por lo tanto, se
CGLIB
la versión en caché del bean (no se crea una nueva).
El alcance predeterminado de
@Bean
s es
SINGLETON
, si especifica un alcance diferente, como
PROTOTYPE
la llamada se pasará al método original.
Tenga en cuenta que esto no es válido para los métodos estáticos . Según los documentos de primavera:
Las llamadas a los métodos estáticos de
@Bean
nunca son interceptadas por el contenedor, ni siquiera dentro de@Configuration
clases de@Configuration
(como se describió anteriormente en esta sección), debido a limitaciones técnicas: la subclase de CGLIB puede anular solo los métodos no estáticos. Como consecuencia, una llamada directa a otro método@Bean
tiene una semántica estándar de Java, lo que resulta en una instancia independiente que se devuelve directamente desde el método de fábrica.
Tengo curiosidad acerca de cómo la inyección de resorte maneja los métodos de llamada con la anotación
@Bean
.
Si pongo una anotación
@Bean
en un método y devuelvo una instancia, entiendo que eso le dice a spring que cree un bean llamando al método y obteniendo la instancia devuelta.
Sin embargo, a veces ese bean tiene que usarse para conectar otros beans o configurar otro código.
La forma habitual de hacerlo es llamar al método anotado
@Bean
para obtener una instancia.
Mi pregunta es, ¿por qué esto no causa que haya múltiples instancias del bean flotando?
Por ejemplo, vea el código a continuación (tomado de otra pregunta).
El método
entryPoint()
está anotado con
@Bean
, por lo que imagino que spring creará una nueva instancia de
BasicAuthenticationEntryPoint
como un bean.
Luego, volvemos a llamar a
entryPoint()
en el bloque de configuración, pero parece que
entryPoint()
devuelve la instancia de bean y no se llama varias veces (intenté iniciar sesión y solo obtuve una entrada de registro).
Potencialmente podríamos llamar a
entryPoint()
varias veces en otras partes de la configuración, y siempre obtendríamos la misma instancia.
¿Es correcto entender esto?
¿Spring hace una reescritura mágica de los métodos anotados con
@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();
}