Skip to content

Top 10 Preguntas Esenciales de Spring

Las 10 Preguntas Más Importantes de Spring

Section titled “Las 10 Preguntas Más Importantes de Spring”

Estas son las preguntas que siempre aparecen en entrevistas técnicas de Spring.


1. ¿Qué es Spring Framework y cuáles son sus módulos principales?

Section titled “1. ¿Qué es Spring Framework y cuáles son sus módulos principales?”

Introducción: Pregunta de apertura en toda entrevista de Spring. Demuestra conocimiento general del ecosistema.

Definición profesional: Spring es un framework de Java que proporciona infraestructura completa para desarrollar aplicaciones empresariales. Su núcleo es el contenedor IoC (Inversión de Control) que gestiona el ciclo de vida de los objetos.

Explicación sencilla: Spring te ayuda a construir aplicaciones Java de forma más fácil: maneja la creación de objetos, conexiones a BD, seguridad, APIs REST, y mucho más.

Funcionamiento básico:

MóduloDescripción
Spring CoreIoC Container, Dependency Injection
Spring MVCFramework web MVC
Spring DataAcceso a datos (JPA, MongoDB, etc.)
Spring SecurityAutenticación y autorización
Spring BootConfiguración automática y arranque rápido
Spring CloudMicroservicios y sistemas distribuidos

Casos de uso reales:

  • APIs REST empresariales
  • Aplicaciones web con MVC
  • Microservicios
  • Integración con bases de datos

Cómo responder en entrevista:

“Spring es un framework de Java para aplicaciones empresariales. Su núcleo es el contenedor IoC que gestiona objetos mediante Dependency Injection. Los módulos principales son: Spring Core para DI, Spring MVC para web, Spring Data para acceso a datos, Spring Security para autenticación, Spring Boot para configuración automática, y Spring Cloud para microservicios.”


2. ¿Qué es Inversión de Control (IoC) y Dependency Injection (DI)?

Section titled “2. ¿Qué es Inversión de Control (IoC) y Dependency Injection (DI)?”

Introducción: Conceptos fundamentales de Spring. Entenderlos es esencial para cualquier desarrollador Spring.

Definición profesional: IoC (Inversión de Control) es un principio donde el framework controla el flujo del programa y la creación de objetos. DI (Dependency Injection) es el patrón que implementa IoC, donde las dependencias se “inyectan” desde fuera en vez de crearse internamente.

Explicación sencilla:

  • Sin DI: Tu clase crea sus propias dependencias (acoplado)
  • Con DI: Alguien más (Spring) te da las dependencias que necesitas (desacoplado)

Funcionamiento básico:

Tipo de InyecciónUsoRecomendación
ConstructorDependencias obligatorias✅ Preferido
SetterDependencias opcionales⚠️ Ocasional
Field (@Autowired)Rápido pero acoplado❌ Evitar

Ejemplo práctico:

IoC y DI
// ❌ SIN Dependency Injection (acoplado)
public class ServicioUsuario {
private RepositorioUsuario repo = new RepositorioUsuarioImpl();
// Problema: no puedes cambiar la implementación ni testear fácilmente
}
// ✅ CON Dependency Injection (desacoplado)
@Service
public class ServicioUsuario {
private final RepositorioUsuario repo;
// Constructor Injection - Spring inyecta automáticamente
public ServicioUsuario(RepositorioUsuario repo) {
this.repo = repo;
}
public Usuario buscar(Long id) {
return repo.findById(id);
}
}
// En tests puedes inyectar un mock fácilmente:
// new ServicioUsuario(mockRepository)

Casos de uso reales:

  • Inyectar repositorios en servicios
  • Inyectar servicios en controladores
  • Facilitar testing con mocks

Cómo responder en entrevista:

“IoC es el principio donde el framework controla la creación y ciclo de vida de los objetos. DI es el patrón que implementa IoC, donde las dependencias se inyectan desde fuera. En Spring, usamos anotaciones como @Service y @Autowired. La forma recomendada es Constructor Injection porque hace las dependencias explícitas, permite inmutabilidad con final, y facilita el testing.”


Introducción: Concepto central de Spring. Todo en Spring gira alrededor de los Beans.

Definición profesional: Un Bean es un objeto cuyo ciclo de vida es gestionado por el contenedor IoC de Spring. Spring se encarga de crear, configurar, inyectar dependencias y destruir estos objetos.

Explicación sencilla: Es cualquier objeto que Spring conoce y maneja por ti. Tú defines qué es un Bean, Spring se encarga del resto.

Funcionamiento básico:

AnotaciónCapaUso
@ComponentGenéricoCualquier componente
@ServiceNegocioLógica de negocio
@RepositoryDatosAcceso a BD
@ControllerWebControladores MVC
@RestControllerWebAPIs REST

Ejemplo práctico:

Definición de Beans
// Forma 1: Anotaciones de estereotipo
@Service
public class UsuarioService {
// Spring lo detecta y gestiona automáticamente
}
// Forma 2: @Bean en clase @Configuration
@Configuration
public class AppConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public ObjectMapper objectMapper() {
return new ObjectMapper()
.registerModule(new JavaTimeModule());
}
}

Casos de uso reales:

  • Servicios de negocio (@Service)
  • Repositorios de datos (@Repository)
  • Configuraciones externas (@Bean)
  • Clientes HTTP, ObjectMapper, etc.

Cómo responder en entrevista:

“Un Bean es un objeto gestionado por el contenedor IoC de Spring. Se pueden definir con anotaciones de estereotipo como @Component, @Service, @Repository, o con @Bean en clases @Configuration. Spring se encarga de instanciarlos, inyectar sus dependencias, y gestionar su ciclo de vida.”


Introducción: Define cuántas instancias de un Bean existen y cuánto tiempo viven.

Definición profesional: El scope de un Bean determina el ciclo de vida y visibilidad de las instancias. El scope por defecto es singleton (una instancia por contenedor).

Explicación sencilla:

  • Singleton: Un solo objeto compartido por todos
  • Prototype: Un objeto nuevo cada vez que lo pides

Funcionamiento básico:

ScopeInstanciasUso
singleton1 por contenedorDefault, stateless
prototypeNueva cada vezStateful, no compartir
request1 por HTTP requestWeb, datos de request
session1 por sesión HTTPWeb, datos de usuario

Ejemplo práctico:

Scopes de Bean
// Singleton (default) - una instancia compartida
@Service
public class UsuarioService {
// Todos usan la misma instancia
}
// Prototype - nueva instancia cada vez
@Component
@Scope("prototype")
public class ReporteGenerator {
private List<String> datos = new ArrayList<>();
// Cada inyección crea una nueva instancia
}
// Request scope - una por request HTTP
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST,
proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestContext {
private String userId;
}

Casos de uso reales:

  • Singleton: Servicios, repositorios, configuraciones
  • Prototype: Objetos con estado, builders
  • Request: Contexto del request actual

Cómo responder en entrevista:

“El scope define cuántas instancias de un Bean existen. El default es singleton: una instancia por contenedor, ideal para servicios stateless. Prototype crea una nueva instancia cada vez, útil para objetos con estado. En aplicaciones web también hay request y session scope. Es importante que los singletons sean thread-safe.”


5. ¿Qué es Spring Boot y qué ventajas ofrece?

Section titled “5. ¿Qué es Spring Boot y qué ventajas ofrece?”

Introducción: Spring Boot es la forma moderna de desarrollar con Spring. Elimina la configuración manual.

Definición profesional: Spring Boot es un proyecto de Spring que simplifica la creación de aplicaciones mediante auto-configuración, servidores embebidos, y convención sobre configuración.

Explicación sencilla: Spring Boot = Spring sin dolor. Configura todo automáticamente para que puedas enfocarte en el código de negocio.

Funcionamiento básico:

CaracterísticaBeneficio
Auto-configuraciónConfigura según dependencias
StartersDependencias pre-empaquetadas
Embedded ServerTomcat/Jetty incluido
ActuatorMonitoreo y métricas
DevToolsHot reload en desarrollo

Ejemplo práctico:

Spring Boot
// Aplicación completa en una clase
@SpringBootApplication
public class MiAplicacion {
public static void main(String[] args) {
SpringApplication.run(MiAplicacion.class, args);
}
}
// @SpringBootApplication =
// @Configuration + @EnableAutoConfiguration + @ComponentScan
// application.yml - configuración simple
// server:
// port: 8080
// spring:
// datasource:
// url: jdbc:postgresql://localhost/db
// username: user
// password: pass

Casos de uso reales:

  • APIs REST
  • Microservicios
  • Aplicaciones web
  • Batch processing

Cómo responder en entrevista:

“Spring Boot simplifica el desarrollo con Spring mediante auto-configuración, starters de dependencias, y servidores embebidos. Con @SpringBootApplication puedes tener una aplicación corriendo en minutos. Incluye Actuator para monitoreo y DevTools para desarrollo. La filosofía es convención sobre configuración: funciona out-of-the-box y solo configuras lo que necesitas cambiar.”


6. ¿Cómo crear un REST Controller en Spring?

Section titled “6. ¿Cómo crear un REST Controller en Spring?”

Introducción: Pregunta práctica esencial. Demuestra conocimiento de Spring MVC y APIs REST.

Definición profesional: Un REST Controller es un componente que maneja requests HTTP y retorna respuestas (generalmente JSON). Se crea con @RestController que combina @Controller + @ResponseBody.

Explicación sencilla: Es donde defines los endpoints de tu API: qué URL responde a qué método y qué datos retorna.

Funcionamiento básico:

AnotaciónMétodo HTTPUso
@GetMappingGETObtener datos
@PostMappingPOSTCrear recurso
@PutMappingPUTActualizar completo
@PatchMappingPATCHActualizar parcial
@DeleteMappingDELETEEliminar

Ejemplo práctico:

REST Controller
@RestController
@RequestMapping("/api/usuarios")
public class UsuarioController {
private final UsuarioService service;
public UsuarioController(UsuarioService service) {
this.service = service;
}
@GetMapping
public List<Usuario> listar() {
return service.findAll();
}
@GetMapping("/{id}")
public ResponseEntity<Usuario> buscar(@PathVariable Long id) {
return service.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Usuario crear(@RequestBody @Valid UsuarioDTO dto) {
return service.save(dto);
}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void eliminar(@PathVariable Long id) {
service.delete(id);
}
}

Casos de uso reales:

  • APIs para frontend (React, Angular)
  • Microservicios
  • Integraciones con terceros

Cómo responder en entrevista:

“Un REST Controller se crea con @RestController y @RequestMapping para definir la URL base. Uso @GetMapping, @PostMapping, etc. para los métodos HTTP. @PathVariable extrae valores de la URL, @RequestBody deserializa el JSON del body, y @Valid activa validaciones. ResponseEntity permite controlar el status code y headers de la respuesta.”


Introducción: Simplifica enormemente el acceso a datos. Elimina el boilerplate de JPA/Hibernate.

Definición profesional: Spring Data JPA es un módulo que simplifica la implementación de repositorios JPA. Genera automáticamente las implementaciones de los métodos de acceso a datos basándose en convenciones de nombres.

Explicación sencilla: Defines una interfaz con métodos como findByNombre(), y Spring genera automáticamente el SQL y la implementación.

Funcionamiento básico:

MétodoSQL Generado
findByNombre(String)WHERE nombre = ?
findByEdadGreaterThan(int)WHERE edad > ?
findByActivoTrue()WHERE activo = true
findByNombreContaining(String)WHERE nombre LIKE %?%

Ejemplo práctico:

Spring Data JPA
// Entidad JPA
@Entity
@Table(name = "usuarios")
public class Usuario {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nombre;
@Column(unique = true)
private String email;
}
// Repository - Spring genera la implementación automáticamente
public interface UsuarioRepository extends JpaRepository<Usuario, Long> {
// Query methods - Spring genera el SQL
Optional<Usuario> findByEmail(String email);
List<Usuario> findByNombreContaining(String nombre);
List<Usuario> findByActivoTrueOrderByNombreAsc();
// Query personalizada con JPQL
@Query("SELECT u FROM Usuario u WHERE u.rol = :rol")
List<Usuario> findByRol(@Param("rol") String rol);
// Query nativa
@Query(value = "SELECT * FROM usuarios WHERE created_at > ?1",
nativeQuery = true)
List<Usuario> findRecientes(LocalDate fecha);
}

Casos de uso reales:

  • CRUD de entidades
  • Búsquedas complejas
  • Paginación y ordenamiento
  • Auditoría automática

Cómo responder en entrevista:

“Spring Data JPA simplifica el acceso a datos generando automáticamente la implementación de repositorios. Solo defino una interfaz que extiende JpaRepository y uso query methods como findByNombre() que Spring convierte a SQL. Para queries complejas uso @Query con JPQL o SQL nativo. También soporta paginación con Pageable y especificaciones para queries dinámicas.”


Introducción: Esencial para operaciones de base de datos. Garantiza consistencia de datos.

Definición profesional: @Transactional es una anotación que gestiona transacciones de base de datos declarativamente. Si el método falla, hace rollback automático; si termina exitosamente, hace commit.

Explicación sencilla: “Todo o nada”: si algo falla dentro del método, todos los cambios a la BD se revierten automáticamente.

Funcionamiento básico:

AtributoDescripción
readOnlyOptimiza lecturas, no permite escrituras
rollbackForExcepciones que causan rollback
propagationCómo se comporta con transacciones existentes
isolationNivel de aislamiento

Ejemplo práctico:

@Transactional
@Service
public class TransferenciaService {
private final CuentaRepository cuentaRepo;
@Transactional // Rollback automático si falla
public void transferir(Long origenId, Long destinoId, BigDecimal monto) {
Cuenta origen = cuentaRepo.findById(origenId)
.orElseThrow(() -> new CuentaNoEncontradaException());
Cuenta destino = cuentaRepo.findById(destinoId)
.orElseThrow(() -> new CuentaNoEncontradaException());
origen.debitar(monto);
destino.acreditar(monto);
cuentaRepo.save(origen);
cuentaRepo.save(destino);
// Si falla aquí, AMBAS operaciones se revierten
}
@Transactional(readOnly = true) // Optimización para lecturas
public List<Cuenta> listar() {
return cuentaRepo.findAll();
}
}

Casos de uso reales:

  • Transferencias bancarias
  • Operaciones que modifican múltiples tablas
  • Cualquier operación que requiera atomicidad

Cómo responder en entrevista:

“@Transactional gestiona transacciones declarativamente. Si el método termina exitosamente hace commit, si lanza una excepción hace rollback. Por defecto solo hace rollback en RuntimeExceptions. Uso readOnly=true para optimizar lecturas. Es importante que el método sea público y llamado desde fuera de la clase para que el proxy de Spring funcione.”


Introducción: Framework de seguridad estándar para aplicaciones Spring. Maneja autenticación y autorización.

Definición profesional: Spring Security es un framework que proporciona autenticación (quién eres), autorización (qué puedes hacer), y protección contra ataques comunes (CSRF, XSS, etc.).

Explicación sencilla:

  • Autenticación: Verificar que eres quien dices ser (login)
  • Autorización: Verificar que tienes permiso para hacer algo (roles)

Funcionamiento básico:

ConceptoDescripción
AuthenticationRepresenta al usuario autenticado
AuthorizationPermisos y roles del usuario
SecurityFilterChainCadena de filtros de seguridad
UserDetailsServiceCarga datos del usuario

Ejemplo práctico:

Spring Security
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.disable()) // Deshabilitar para APIs REST
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.requestMatchers("/api/**").authenticated()
)
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.httpBasic(Customizer.withDefaults())
.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}

Casos de uso reales:

  • Autenticación con JWT
  • Control de acceso por roles
  • OAuth2 / OpenID Connect
  • Protección de APIs REST

Cómo responder en entrevista:

“Spring Security maneja autenticación y autorización. La configuración moderna usa SecurityFilterChain para definir reglas de acceso. Uso requestMatchers para definir qué endpoints son públicos, cuáles requieren autenticación, y cuáles requieren roles específicos. Para APIs REST típicamente deshabilito CSRF y uso sesiones stateless con JWT.”


10. ¿Cómo manejar excepciones en Spring?

Section titled “10. ¿Cómo manejar excepciones en Spring?”

Introducción: Tema práctico importante. Un buen manejo de errores mejora la experiencia del API.

Definición profesional: Spring permite manejar excepciones de forma centralizada usando @RestControllerAdvice y @ExceptionHandler, convirtiendo excepciones en respuestas HTTP apropiadas.

Explicación sencilla: En lugar de try-catch en cada controlador, defines un manejador global que captura excepciones y retorna respuestas de error consistentes.

Funcionamiento básico:

AnotaciónUso
@RestControllerAdviceClase que maneja excepciones globalmente
@ExceptionHandlerMétodo que maneja un tipo de excepción
@ResponseStatusDefine el código HTTP de respuesta

Ejemplo práctico:

Manejo de Excepciones
// Excepción personalizada
public class UsuarioNoEncontradoException extends RuntimeException {
public UsuarioNoEncontradoException(Long id) {
super("Usuario no encontrado: " + id);
}
}
// Manejador global de excepciones
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UsuarioNoEncontradoException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorResponse handleNotFound(UsuarioNoEncontradoException ex) {
return new ErrorResponse(404, ex.getMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ErrorResponse handleValidation(MethodArgumentNotValidException ex) {
List<String> errores = ex.getBindingResult()
.getFieldErrors()
.stream()
.map(e -> e.getField() + ": " + e.getDefaultMessage())
.toList();
return new ErrorResponse(400, "Validación fallida", errores);
}
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ErrorResponse handleGeneral(Exception ex) {
return new ErrorResponse(500, "Error interno");
}
}
// DTO de respuesta de error
public record ErrorResponse(int status, String mensaje, Object... detalles) {}

Casos de uso reales:

  • Recursos no encontrados (404)
  • Errores de validación (400)
  • Errores de autenticación (401/403)
  • Errores internos (500)

Cómo responder en entrevista:

“Uso @RestControllerAdvice para manejar excepciones globalmente. Defino métodos con @ExceptionHandler para cada tipo de excepción, retornando un DTO de error consistente con el código HTTP apropiado. Esto centraliza el manejo de errores y garantiza respuestas uniformes en toda la API. También manejo MethodArgumentNotValidException para errores de validación de @Valid.”


🐝