Spring: @Component versus @Bean

Entiendo que la anotación de @Component se introdujo en la spring 2.5 para deshacerse de la definición de xml bean mediante el uso del análisis de classpath.

@Bean se introdujo en la spring 3.0 y se puede usar con @Configuration para eliminar por completo el archivo xml y usar java config en su lugar.

¿Habría sido posible volver a utilizar la anotación @Component lugar de introducir la anotación @Bean ? Tengo entendido que el objective final es crear frijoles en ambos casos.

@Component y @Bean hacen dos cosas bastante diferentes, y no deben confundirse.

@Component (y @Service y @Repository ) se usan para autodetectar y autoconfigurar beans usando el escaneo classpath. Existe un mapeo uno a uno implícito entre la clase anotada y el bean (es decir, un bean por clase). El control del cableado es bastante limitado con este enfoque, ya que es puramente declarativo.

@Bean se usa para declarar explícitamente un solo bean, en lugar de dejar que Spring lo haga automáticamente como se @Bean anteriormente. Desvincula la statement del bean de la definición de la clase, y le permite crear y configurar los beans exactamente como lo elija.

Para responder tu pregunta…

¿Hubiera sido posible volver a utilizar la anotación @Component lugar de introducir la anotación @Bean ?

Claro, probablemente; pero eligieron no hacerlo, ya que los dos son bastante diferentes. La spring ya es lo suficientemente confusa sin ensuciar aún más las aguas.

@Component Preferible para el escaneo de componentes y el cableado automático.

¿Cuándo deberías usar @Bean ?

A veces, la configuración automática no es una opción. ¿Cuando? Imaginemos que desea conectar componentes desde bibliotecas de terceros (no tiene el código fuente, por lo que no puede anotar sus clases con @Component), por lo que la configuración automática no es posible.

La anotación @Bean devuelve un objeto que el resorte debe registrar como bean en el contexto de la aplicación. El cuerpo del método tiene la lógica responsable de crear la instancia.

Consideremos que quiero una implementación específica dependiendo de algún estado dynamic. @Bean es perfecto para ese caso.

 @Bean @Scope("prototype") public SomeService someService() { switch (state) { case 1: return new Impl1(); case 2: return new Impl2(); case 3: return new Impl3(); default: return new Impl(); } } 

Sin embargo, no hay forma de hacerlo con @Component .

Ambos enfoques apuntan a registrar el tipo de objective en el contenedor Spring.

La diferencia es que @Bean es aplicable a los métodos , mientras que @Component es aplicable a los tipos .

Por lo tanto, cuando utiliza la anotación @Bean , controla la lógica de creación de instancias en el cuerpo del método (vea el ejemplo anterior ). Con la anotación @Component no puedes.

Cuando usas la etiqueta @Component , es lo mismo que tener un POJO (Objeto Java simple normal) con un método de statement de vainilla (anotado con @Bean ). Por ejemplo, los siguientes métodos 1 y 2 darán el mismo resultado.

Método 1

 @Component public class SomeClass { private int number; public SomeClass(Integer theNumber){ this.number = theNumber.intValue(); } public int getNumber(){ return this.number; } } 

con un frijol para ‘theNumber’:

 @Bean Integer theNumber(){ return new Integer(3456); } 

Método 2

 //Note: no @Component tag public class SomeClass { private int number; public SomeClass(Integer theNumber){ this.number = theNumber.intValue(); } public int getNumber(){ return this.number; } } 

con los frijoles para ambos:

 @Bean Integer theNumber(){ return new Integer(3456); } @Bean SomeClass someClass(Integer theNumber){ return new SomeClass(theNumber); } 

El Método 2 le permite mantener juntas las declaraciones de frijoles, es un poco más flexible, etc. Es posible que desee agregar otro grano SomeClass no vainilla como el siguiente:

 @Bean SomeClass strawberryClass(){ return new SomeClass(new Integer(1)); } 
  1. @Component detecta automáticamente y configura los beans usando classpath scanning donde @Bean declara explícitamente un solo bean, en lugar de dejar que Spring lo haga automáticamente.
  2. @Component no desacopla la statement del bean de la definición de la clase donde @Bean desacopla la statement del bean de la definición de la clase.
  3. @Component es una anotación de nivel de clase donde @Bean es una anotación de nivel de método y el nombre del método sirve como nombre de bean.
  4. @Component no necesita ser utilizado con la anotación @Configuration donde debe usarse la anotación @Bean dentro de la clase que está anotada con @Configuration .
  5. No podemos crear un bean de una clase usando @Component, si la clase está fuera del contenedor de spring, ya que podemos crear un bean de una clase usando @Bean, incluso si la clase está presente fuera del contenedor de spring .
  6. @Component tiene diferentes especializaciones como @ Controller, @ Repository y @Service donde @Bean no tiene especializaciones .
  • @component y sus especializaciones (@Controller, @service, @repository) permiten la autodetección utilizando el escaneo classpath. Si vemos que la clase de componente como @Controller, @service, @repository se escaneará automáticamente por el marco de spring utilizando el escaneo de componentes.
  • @Bean, por otro lado, solo se puede usar para declarar explícitamente un solo bean en una clase de configuración.
  • @Bean solía declarar explícitamente un solo bean, en lugar de dejar que la spring lo hiciera automáticamente. Hace una statement septada de frijol de la definición de la clase.
  • En resumen, @Controller, @service, @repository son para autodetección y @Bean para crear beans seprados de la clase
     - @Controlador
     clase pública LoginController 
     {--code--}

     - @Configuration
     clase pública AppConfig {
     @Frijol
     public SessionFactory sessionFactory () 
     {--code--}

@Component Esta es una anotación genérica y se puede aplicar a cualquier clase de la aplicación para que sea un componente manejado por resorte (simplemente, el estereotipo genérico para cualquier componente manejado por resorte). cuando el classpath es escaneado por la función componente-escaneo de spring (@ComponentScan) , identificará las clases anotadas con la anotación @Component (dentro del paquete dado) y creará los beans de dichas clases y las registrará en ApplicationContext. @Component es una anotación de nivel de clase y su propósito es hacer que la clase sea un componente administrado por resorte y un bean autodetectable para la función de escaneo classpath.

si desea obtener más información sobre @Component y otras anotaciones de estereotipos, se recomienda consultar este artículo.

@Bean se usa para declarar y registrar explícitamente un bean (como un bean de configuración) en el contenedor Spring IOC que se devuelve de un método. @Bean es una anotación de nivel de método y se usa dentro de una clase que está anotada con @Configuration . Simplemente, la anotación @Bean se usa para registrar el bean devuelto por un método como un bean de configuración de spring en IOC Container. @Bean es solo una anotación de nivel de método y no se puede usar con clases y statement de objeto.

La anotación @Bean indica que un método produce un bean que debe ser administrado por el contenedor Spring.

Para declarar un bean, simplemente anote un método con la anotación @Bean . Cuando JavaConfig encuentre dicho método, ejecutará ese método y registrará el valor de retorno como un bean dentro de un ApplicationContext. Por defecto, el nombre del bean será el mismo que el nombre del método. El siguiente es un ejemplo simple de una statement de método @Bean.

 @Configuration public class ApplicationConfig { @Bean public User adminUserProfile() { return new User("Rami","Nassar"); } } 

En la clase ApplicationConfig, puede ver que primero usamos la anotación @Configuration para informar a Spring que este es un archivo de configuración basado en Java. Posteriormente, la anotación @Bean se utiliza para declarar un bean Spring y los requisitos DI. La anotación @Bean es equivalente a la tag, el nombre del método es equivalente al atributo id dentro del etiqueta. Espero que después de leer este artículo, tengas una idea clara sobre el verdadero propósito y uso de las anotaciones @Bean y @Component .