CodeGym /Cursos /Módulo 5. Spring /Práctica: anotaciones @Component, @Autowired, @Bean

Práctica: anotaciones @Component, @Autowired, @Bean

Módulo 5. Spring
Nivel 2 , Lección 4
Disponible

Ahora vamos a ver las anotaciones en la práctica para que quede más claro.

1. Anotación @Component — la magia de crear beans

La anotación @Component convierte una clase Java normal en un Spring Bean que el contenedor IoC de Spring gestiona automáticamente. Es como si le dijeras a un agente especial llamado Spring: "Ocúpate de esta clase, crea su instancia e inyéctala cuando haga falta".

Por debajo, el contenedor IoC escanea las clases del proyecto mediante el mecanismo Component Scan, y busca todas las clases marcadas con @Component.

Ejemplo de uso de @Component


import org.springframework.stereotype.Component;

// Con la anotación indicamos que esta clase es un componente (bean)
@Component
public class CoffeeMaker {
    public String makeCoffee() {
        return "☕ ¡Café listo!";
    }
}

Ahora CoffeeMaker está registrado en el contenedor IoC. Puedes obtenerlo donde quieras y Spring creará la instancia de esa clase por ti.

Analogía: si fueras el contenedor Spring, @Component sería la señal "Agrégalo a mi lista de responsabilidades".


2. Anotación @Autowired: el arte de la inyección de dependencias

Cuando marcamos algo con @Autowired, le decimos a Spring: "¡Busca y conecta el componente que haga falta tú mismo!". Spring busca el bean adecuado (por ejemplo, nuestro CoffeeMaker) y lo añade vía campo, constructor o setter.

Inyección por campo

Este modo es el más sencillo, pero tiene sus inconvenientes (ver "Errores típicos" abajo).


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Barista {

    // Le decimos a Spring: "¡Inyecta aquí CoffeeMaker!"
    @Autowired
    private CoffeeMaker coffeeMaker;

    public void serveCoffee() {
        System.out.println(coffeeMaker.makeCoffee());
    }
}

Marcando el campo con @Autowired indicamos a Spring que debe inicializarlo antes del primer uso. Ahora, cuando arranquemos la aplicación, Barista sabrá cómo servir el café.

Inyección por constructor

Forma recomendada: hace las dependencias "visibles" y facilita el testing.


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Barista {

    private final CoffeeMaker coffeeMaker;

    // Spring llamará a este constructor y le pasará CoffeeMaker
    @Autowired
    public Barista(CoffeeMaker coffeeMaker) {
        this.coffeeMaker = coffeeMaker;
    }

    public void serveCoffee() {
        System.out.println(coffeeMaker.makeCoffee());
    }
}

Inyección por setter

Útil si las dependencias pueden cambiar en runtime (poco común, pero puede pasar).


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Barista {

    private CoffeeMaker coffeeMaker;

    @Autowired
    public void setCoffeeMaker(CoffeeMaker coffeeMaker) {
        this.coffeeMaker = coffeeMaker;
    }

    public void serveCoffee() {
        System.out.println(coffeeMaker.makeCoffee());
    }
}

Consejo: si la dependencia es obligatoria, usa el constructor. Si no lo es — usa el setter.


3. Anotación @Bean — crear beans personalizados

La anotación @Bean se usa para indicar explícitamente a Spring que un método dentro de una clase de configuración crea un bean. Este enfoque es útil cuando no puedes o no quieres modificar la clase original (por ejemplo, si viene de una librería externa).

Ejemplo de uso de @Bean


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// Indicamos que esta clase es una configuración Java
@Configuration
public class CoffeeConfig {

    // Este método crea el objeto CoffeeMaker
    @Bean
    public CoffeeMaker coffeeMaker() {
        return new CoffeeMaker();
    }
}

Ahora, en lugar de @Component, hemos declarado explícitamente que la clase CoffeeMaker se crea mediante el método coffeeMaker. Spring igualmente lo añadirá al contenedor IoC.


4. Uso práctico de todas las anotaciones

Ahora juntemos todo en una pequeña aplicación.

Clase 1: CoffeeMaker


import org.springframework.stereotype.Component;

@Component
public class CoffeeMaker {
    public String makeCoffee() {
        return "☕ ¡Café listo!";
    }
}

Clase 2: Barista


import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;

@Component
public class Barista {

    private final CoffeeMaker coffeeMaker;

    @Autowired
    public Barista(CoffeeMaker coffeeMaker) {
        this.coffeeMaker = coffeeMaker;
    }

    public void serveCoffee() {
        System.out.println(coffeeMaker.makeCoffee());
    }
}

Clase 3: CoffeeShopConfig (usando @Bean)


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CoffeeShopConfig {

    @Bean
    public String coffeeRecipe() {
        return "Receta de café: tomar café, añadir agua y amor!";
    }
}

Clase principal para ejecutar


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class CoffeeShopApplication {

    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(CoffeeShopApplication.class, args);

        // Obtenemos Barista del contenedor IoC
        Barista barista = context.getBean(Barista.class);
        barista.serveCoffee();

        // También está disponible el bean con la receta de café
        String recipe = context.getBean(String.class);
        System.out.println(recipe);
    }
}

5. Errores típicos y cómo evitarlos

Falta del bean

Si no marcas la clase con @Component ni defines un método con @Bean, Spring no la añadirá al contenedor IoC. Al final obtendrás una NoSuchBeanDefinitionException.

Múltiples candidatos para @Autowired

Cuando Spring encuentra dos beans del mismo tipo, no sabe cuál usar. Aquí ayuda la anotación @Qualifier.


@Autowired
@Qualifier("specialCoffeeMaker")
private CoffeeMaker coffeeMaker;

Dependencias inaccesibles

Si intentas inyectar dependencias por campo, pero está declarado private y no hay ni constructor ni setter, Spring no podrá hacer DI. La solución es obvia: usa constructores o setters.


Ahora sabes cómo trabajar con las anotaciones @Component, @Autowired y @Bean. Estos conceptos forman la base para escribir aplicaciones flexibles y modulares en Spring Framework. Ahora toca practicar.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION