Curso de Spring Boot

En este capítulo aprenderemos cómo funciona Spring Boot internamente.

Entender esto es muy importante, porque es la base de todo lo que haremos después.

Veremos:

  • qué es un Bean
  • qué es la inyección de dependencias
  • cómo funciona el contenedor de Spring
  • las anotaciones más importantes

3.1 Qué es el contenedor de Spring

El corazón de Spring es el contenedor de Spring.

El contenedor es el sistema que se encarga de:

  • crear objetos
  • gestionar dependencias
  • conectar los objetos entre sí
  • controlar su ciclo de vida

Sin Spring

En Java tradicional el programador crea los objetos manualmente.

Ejemplo:

1UserRepository repository = new UserRepository();
2UserService service = new UserService(repository);

El programador debe:

  • crear objetos
  • pasar dependencias
  • gestionar todo manualmente

Con Spring

Spring crea y conecta los objetos automáticamente.

1@Service
2public class UserService {
3
4    private final UserRepository repository;
5
6    public UserService(UserRepository repository) {
7        this.repository = repository;
8    }
9
10}

Spring detecta la dependencia y la inyecta automáticamente.


3.2 Qué es un Bean

Un Bean es simplemente un objeto gestionado por Spring.

Cuando Spring crea un objeto y lo controla, ese objeto se llama Bean.

Ejemplos de Beans:

  • controladores
  • servicios
  • repositorios
  • componentes

Ejemplo de Bean

1@Service
2public class UserService {
3
4}

Aquí UserService se convierte en un Bean.

Spring lo crea automáticamente cuando arranca la aplicación.


3.3 Inyección de dependencias

La inyección de dependencias (Dependency Injection) es el mecanismo que usa Spring para conectar objetos.

La idea es simple:

Un objeto no crea sus dependencias.

Spring se las proporciona.


Ejemplo simple

Repositorio:

1@Repository
2public class UserRepository {
3
4}

Servicio:

1@Service
2public class UserService {
3
4    private final UserRepository repository;
5
6    public UserService(UserRepository repository) {
7        this.repository = repository;
8    }
9
10}

Spring hace esto automáticamente:

1UserRepository repository = new UserRepository();
2UserService service = new UserService(repository);

Pero sin que el programador tenga que hacerlo.


3.4 Por qué es importante la inyección de dependencias

La inyección de dependencias tiene varias ventajas:

Código más limpio

Los objetos no crean sus dependencias.


Código más fácil de probar

En tests podemos sustituir dependencias fácilmente.


Menor acoplamiento

Las clases dependen de interfaces o servicios, no de implementaciones concretas.


3.5 Anotaciones más importantes de Spring

Spring usa anotaciones para indicar qué clases deben ser gestionadas.

Las más importantes son:

anotaciónfunción
@ComponentBean genérico
@Servicelógica de negocio
@Repositoryacceso a datos
@Controllercontrolador web
@RestControllercontrolador REST

3.6 @Component

@Component es la anotación más básica.

Convierte una clase en un Bean de Spring.

Ejemplo:

1@Component
2public class EmailService {
3
4}

Spring crea automáticamente el objeto.


3.7 @Service

@Service se usa para la lógica de negocio.

Ejemplo:

1@Service
2public class UserService {
3
4    public String getUserName() {
5        return "Ana";
6    }
7
8}

3.8 @Repository

@Repository se usa para acceso a base de datos.

Ejemplo:

1@Repository
2public class UserRepository {
3
4}

Normalmente se usa junto con Spring Data JPA.


3.9 @RestController

@RestController define un controlador de API.

Ejemplo:

1@RestController
2public class HelloController {
3
4    @GetMapping("/hello")
5    public String hello() {
6        return "Hola mundo";
7    }
8
9}

Spring automáticamente:

  • detecta el controlador
  • registra la ruta /hello
  • devuelve la respuesta en JSON o texto

3.10 Flujo típico de una API

Una aplicación Spring Boot suele seguir esta estructura:

Cliente → Controller → Service → Repository → Base de datos

Ejemplo completo

Controller

1@RestController
2public class UserController {
3
4    private final UserService service;
5
6    public UserController(UserService service) {
7        this.service = service;
8    }
9
10    @GetMapping("/user")
11    public String getUser() {
12        return service.getUserName();
13    }
14
15}

Service

1@Service
2public class UserService {
3
4    public String getUserName() {
5        return "Carlos";
6    }
7
8}

Flujo

  1. cliente llama a /user
  2. controller recibe petición
  3. controller llama al service
  4. service devuelve resultado
  5. controller devuelve respuesta

3.11 Qué hace @SpringBootApplication

La anotación:

1@SpringBootApplication

es una combinación de tres anotaciones.

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan

Qué hacen

ComponentScan

Busca clases con:

@Component
@Service
@Repository
@Controller

y las registra como Beans.


EnableAutoConfiguration

Spring configura automáticamente:

  • servidor web
  • JSON
  • base de datos
  • seguridad

3.12 Escaneo de componentes

Spring escanea automáticamente las clases dentro del mismo paquete.

Ejemplo:

com.example.demo

Si la clase principal está aquí:

DemoApplication

Spring escaneará:

com.example.demo.*

Por eso es importante organizar bien los paquetes.


3.13 Buenas prácticas

Estructura recomendada:

controller
service
repository
entity
dto
config

Ejemplo:

com.example.app

controller
service
repository
entity
  • Loading...